通过callgrind运行我的应用程序显示,这条线路使其他所有内容相形见绌大约10,000倍。我可能会围绕它重新设计,但它让我感到疑惑;有没有更好的方法呢?
这就是我现在正在做的事情:
int i = 1;
while
(
(
(*(buffer++) == 0xffffffff && ++i) ||
(i = 1)
)
&&
i < desiredLength + 1
&&
buffer < bufferEnd
);
它正在寻找32位无符号整数数组中第一块desiredLength 0xffffffff值的偏移量。
它比我可能想出的涉及内循环的任何实现快得多。但它仍然太慢了。
答案 0 :(得分:4)
我也会考虑search_n
的建议,因为我很确定它能做到这一点。它实际上非常简单,基本上可以通过expect_length因子来加速。除非目标值在数组中非常密集。
以下是这样的想法:如果从位置K
开始有I
个连续值的实例,那么位置I + K - 1
必须包含该值。所以你先检查一下;如果没有,则可能包含K个连续值的最早位置为I + K
,因此您可以在那里重新启动算法。
另一方面,如果您在I + K - 1
处找到值,则向后扫描,直到您达到I
(在这种情况下您成功),或者您到达某个位置{{1其中不包含目标值。在后一种情况下,您知道有J - 1
到J
的目标值,因此您现在可以检查I + K - 1
。如果可行,您只需向后扫描到J + K - 1
。如果它不起作用,则在I + K
重新启动算法。
大多数情况下,您只会查看向量中的每个J + K
位置。对于较大的K'th
,这是一个很大的胜利。
答案 1 :(得分:3)
您标记了c ++,因此我假设您有可用的STL算法:
std::search_n(buffer, bufferEnd, desiredLength, 0xffffffff);
答案 2 :(得分:2)
尝试使用C标准库中的memcmp
。现代编译器应具有非常优化的memxxx
函数实现,从而使现代CPU的速度最快。
答案 3 :(得分:2)
只是一个想法,但你一次迭代int数组一个吗?考虑一下,如果*(buffer) != 0xffffffff
和buffer[desiredLength-1] != 0xffffffff
,那么您可以确定两者之间没有任何关系,这样您就可以buffer
移动desiredLength
而不仅仅是desiredLength
如果*(buffer)
远大于1,则可以显着提高您的速度。当然,它会使你的功能变得复杂,因为:
buffer[desiredLength-1]
和0xffffffff
都等于*(buffer)
,那么你不能认为它们之间是连续的,所以你仍然需要检查它。0xffffffff
不等于buffer[desiredLength-1]
但0xffffffff
等于0xffffffff
,那么您必须跟踪buffer[desiredLength-1]
序列的开头。 有点复杂,但可能加快速度。希望这是有道理的。
答案 4 :(得分:1)
如果我想实现这一点,我会使用memchr
和memcmp
来实现:
bool found = false;
std::vector<unsigned char> tmp(desiredLength*sizeof(uint32_t), 0xFF);
while( true ) {
void* p = memchr(bufferStart, 0xFF,
(bufferEnd-bufferStart-desiredLength) * sizeof(uint32_t));
if( !p ) break;
if( !memcmp(p, &tmp[0], desiredLength * sizeof(uint32_t)) ) {
found = true;
break;
}
}
此外,您可以使用可能比您自己的代码更优化的std::search_n
答案 5 :(得分:0)
当std::search_n
不可用时:
int i = 1;
while
(
(
i == 1
&&
buffer < bufferEnd
&&
(
(
*buffer == desired
&&
*(buffer + desiredLength - 1) == desired
&&
(i = 3)
)
||
(buffer += desiredLength && (i = 1))
)
)
||
(
i == 2
&&
(
(
buffer > arr
&&
(*(--buffer) == desired)
)
||
(i = 3)
)
)
||
(
i >= 3
&&
buffer < bufferEnd
&&
(
(
*(buffer++) == desired
&&
(i++ || true)
)
||
(i = 1)
)
&&
(
i < 3
||
i - 3 < desiredLength + 1
)
)
);
buffer -= i - 4;
if (buffer > bufferEnd - (i-3))
buffer = bufferEnd;
返回相同的结果,仅略慢于std:search_n
:
buffer = std::search_n(buffer, bufferEnd-1, desiredLength, desired);
if (buffer == bufferEnd-1)
buffer = bufferEnd;