![](/img/trans.png)
[英]What is the most efficient algorithm to find a longest chain from a set of ordered pairs (x, y)?
[英]What is the most efficient method to find x contiguous values of y in an array?
通過callgrind運行我的應用程序顯示,這一行使其他所有內容相形見絀大約10,000。 我可能會圍繞它重新設計,但它讓我感到疑惑; 有沒有更好的方法呢?
這就是我現在正在做的事情:
int i = 1;
while
(
(
(*(buffer++) == 0xffffffff && ++i) ||
(i = 1)
)
&&
i < desiredLength + 1
&&
buffer < bufferEnd
);
它正在尋找32位無符號整數數組中第一塊desiredLength 0xffffffff值的偏移量。
它比任何涉及內循環的實現都要快得多。 但它仍然太慢了。
我也會去尋找search_n
建議,因為我很確定它能做到這一點。 它實際上非常簡單,基本上可以通過expect_length因子來加速。 除非目標值在數組中非常密集。
這是一個想法:如果從位置I
開始有K
個連續的值實例,則必須是位置I + K - 1
包含該值的情況。 所以你先檢查一下; 如果沒有,那么可能包含K個連續值的最早位置是I + K
,因此您可以在那里重新啟動算法。
另一方面,如果你在I + K - 1
處找到值,那么你向后掃描直到你到達I
(在這種情況下你成功),或者你到達某個位置J - 1
,它不包含目標值。 在后一種情況下,您知道有從J
到I + K - 1
目標值,因此您現在檢查J + K - 1
。 如果可行,您只需向后掃描到I + K
如果它不起作用,則在J + K
重新啟動算法。
大多數情況下,您只會查看向量中的每個第K'th
位置。 對於大K
,這是一個巨大的勝利。
你標記了c ++所以我假設你有STL算法可用:
std::search_n(buffer, bufferEnd, desiredLength, 0xffffffff);
嘗試使用C標准庫中的memcmp
。 現代編譯器應具有非常優化的memxxx
函數實現, memxxx
使現代CPU的速度最快。
只是一個想法,但你一次迭代int數組一個嗎? 考慮一下,如果*(buffer) != 0xffffffff
和buffer[desiredLength-1] != 0xffffffff
那么你可以確定在兩者之間檢查是沒有意義的,所以你可以通過desiredLength
而不是僅僅1來移動buffer
。可以顯著提高你的速度,如果desiredLength
比1大得多。 當然它會使你的功能變得復雜,因為:
*(buffer)
和buffer[desiredLength-1]
等於0xffffffff
那么你不能認為它們之間是連續的,所以你仍然需要檢查它。 *(buffer)
不等於0xffffffff
但buffer[desiredLength-1]
確實等於0xffffffff
那么你必須跟蹤到0xffffffff
序列的開頭。 buffer[desiredLength-1]
時,你必須確保不要超出buffer[desiredLength-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
,它可能比您自己的代碼更優化
當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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.