3
  • 您多久使用一次按位运算“hacks”进行某种优化?在什么样的情况下它真的有用?

示例:而不是使用 if:

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

你写:

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

当然,假设它对这种特定情况执行相同的预期结果。

  • 这值得么?我觉得不可读。你经常遇到这种情况吗?

注意:我在选择的答案中看到了这段代码:为什么处理排序数组比处理未排序数组更快?

4

3 回答 3

2

虽然该代码是显示正在发生的事情的绝佳方式,但我通常不会使用这样的代码。如果必须要快,通常会有更快的解决方案,例如在 x86 上使用 SSE 或在 ARM 上使用 NEON。如果这些都不可用,当然,我会使用它,只要它有帮助并且是必要的。

顺便说一下,我在这个答案中解释了它是如何工作的

像 Skylion 一样,我经常使用的一件事是弄清楚一个数字是否是 2 的幂。想一想你会如何做到这一点..然后看看这个:(x & (x - 1)) == 0 && x != 0

我想你第一次看到它时会很棘手,但是一旦你习惯了它,它就会比任何不使用位数学的替代方案简单得多。它之所以有效,是因为从数字中减去 1 意味着借位从数字的最右端开始并贯穿所有零,然后在第一个变成零的 1 处停止。将该数字与原始数字进行与运算,然后使最右边的 1 为零。2 的幂只有一个 1,它消失了,留下零。所有其他数字将至少有一个 1,除了零,这是一种特殊情况。一个常见的变体不会测试零,并且可以将其视为 2 的幂,或者知道不会发生零。

同样,您可以使用 bitmath 轻松完成其他一些事情,但如果没有它就不会那么容易。正如他们所说,为工作使用正确的工具。有时位数学是正确的工具。

于 2013-10-14T08:59:13.587 回答
1

Bitwise operations are so useful that prof. Knuth wrote a book abot them: http://www.amazon.com/The-Computer-Programming-Volume-Fascicle/dp/0321580508

Just to mention a few simplest ones: int multiplication and division by a power of two (using left and right shift), mod with respect to a power of two, masking and so on. When using bitwise ops just be sure to provide sufficient comments about what's going on.

However, your example, data[c]>128 is not applicable IMO, just keep it that way. But if you want to compute data[c] % 128 then data[c] & 0x7f is much faster (where & represents bitwise AND).

于 2013-10-14T09:06:54.117 回答
1

在某些情况下,使用此类 hack 可能会很有用。例如,他们可以删除一些 Java 虚拟机“优化”,例如分支预测器。我发现它们在少数情况下只有一次有用。主要的是乘以-1。如果您在一个庞大的数组中执行数百次,那么简单地翻转第一位比实际多次翻转更有效。我用它的另一个例子是知道一个数字是否是 2 的幂(因为它很容易用二进制计算出来。)基本上,当你想作弊时,位黑客很有用。这是一个人类的类比。如果您有数字列表并且需要知道它们是否大于 29,您可以自动知道第一个数字是否大于 3,那么整个数字是否大于 30,反之亦然。

于 2013-10-14T03:47:01.430 回答