2013-10-14 111 views
3
  • 您經常使用按位運算「hacks」來做某種 優化?它在哪種情況下真的有用?

示例:而不是使用如:使用按位運算

if (data[c] >= 128) //in a loop 
    sum += data[c]; 

你寫:

int t = (data[c] - 128) >> 31; 
sum += ~t & data[c]; 

當然假設它爲這個具體情況相同的預期結果。

  • 它值得嗎?我覺得它是不可讀的。你多久碰到一次這樣的問題?

注:我看到這個代碼在這裏選擇的答案:Why is processing a sorted array faster than an unsorted array?

+0

數組是排序的嗎?數據多久才符合if語句? 50%,25%,75%? – Skylion

+0

那麼在另一個問題,排序使它更有效率..但我問的是使用按位運算來做同樣的優化沒有排序或使用if()..我更關心的可讀性和是否是矯枉過正 – Memo

+1

這取決於。 if語句每秒被使用1,000,000次? (Exageration)在某些應用程序中,如信號處理中處理能力造成瓶頸的位運算非常有用。 – Skylion

回答

1

按位操作非常有用,Knuth在他們的書中寫下了一本書:http://www.amazon.com/The-Computer-Programming-Volume-Fascicle/dp/0321580508

只是提到幾個最簡單的問題:int乘法和除以2的冪(使用左右移位),mod關於2的冪,掩蔽等等。在使用按位操作時,請務必提供有關正在發生的事情的足夠評論。

但是,您的示例data[c]>128不適用IMO,只是保持它的方式。 但是如果你想計算data[c] % 128那麼data[c] & 0x7f要快得多(其中&代表按位AND)。

1

有幾種情況,其中使用這些黑客可能是有用的。例如,他們可以刪除一些Java虛擬機「優化」,如分支預測器。我發現它們在少數情況下只能使用一次。主要的是乘以-1。如果你在一個龐大的數組中執行數百次,那麼簡單地翻轉第一位比實際多位更高效。我使用過的另一個例子是知道一個數是否是2的冪(因爲它很容易用二進制來表示)。基本上,當你想要作弊時,有點黑客是有用的。這是一個人類的比喻。如果你有數字列表,你需要知道它們是否大於29,你可以自動知道第一個數字是否大於3,那麼整個數字大於30,反之亦然。按位操作只是允許你對二進制執行類似的作弊。

1

雖然該代碼是一個很好的方式來顯示發生了什麼,我通常不會使用這樣的代碼。如果速度很快,通常會有更快的解決方案,例如在x86上使用SSE或在ARM上使用NEON。如果沒有可用的,當然,我會使用它,只要它有幫助並且是必要的。

順便說一句,我將解釋它是如何工作in this answer

像Skylion,我用了很多被搞清楚一個數是否爲二的冪的一件事。想一想你會怎麼做......然後看看這個:(x & (x - 1)) == 0 && x != 0

我第一次看到它會很棘手,但是一旦你習慣了它,它會比任何替代品都簡單得多不使用位圖。它的工作原理是因爲從數字中減去1意味着借入從數字的最右端開始並遍歷所有的零,然後在第一個變爲零時停止。與原來的數字進行比較,然後使最右邊的1爲零。兩個權力只有一個1,消失,留下零。所有其他數字將剩下至少一個1,除了零以外,這是一種特殊情況。一個常見的變體不會測試爲零,並且可以將其視爲兩個冪或知道零不會發生。

同樣,還有其他的事情,你可以很容易地做的比特,但沒有那麼容易沒有。正如他們所說,使用正確的工具來完成這項工作。有時候,比特幣是正確的工具。