2013-10-14 67 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,除了零以外,这是一种特殊情况。一个常见的变体不会测试为零,并且可以将其视为两个幂或知道零不会发生。

同样,还有其他的事情,你可以很容易地做的比特,但没有那么容易没有。正如他们所说,使用正确的工具来完成这项工作。有时候,比特币是正确的工具。