Is shifting bits faster than multiplying and divid

2019-01-01 13:49发布

Shifting bits left and right is apparently faster than multiplication and division operations on most, maybe even all, CPUs if you happen to be using a power of 2. However, it can reduce the clarity of code for some readers and some algorithms. Is bit-shifting really necessary for performance, or can I expect the compiler or VM to notice the case and optimize it (in particular, when the power-of-2 is a literal)? I am mainly interested in the Java and .NET behavior but welcome insights into other language implementations as well.

13条回答
其实,你不懂
2楼-- · 2019-01-01 13:53

You can almost certainly depend on the literal-power-of-two multiplication optimisation to a shift operation. This is one of the first optimisations that students of compiler construction will learn. :)

However, I don't think there's any guarantee for this. Your source code should reflect your intent, rather than trying to tell the optimiser what to do. If you're making a quantity larger, use multiplication. If you're moving a bit field from one place to another (think RGB colour manipulation), use a shift operation. Either way, your source code will reflect what you are actually doing.

查看更多
初与友歌
3楼-- · 2019-01-01 13:58

Most compilers will turn multiplication and division into bit shifts when appropriate. It is one of the easiest optimizations to do. So, you should do what is more easily readable and appropriate for the given task.

查看更多
闭嘴吧你
4楼-- · 2019-01-01 14:00

I am stunned as I just wrote this code and realized that shifting by one is actually slower than multiplying by 2!

(EDIT: changed the code to stop overflowing after Michael Myers' suggestion, but the results are the same! What is wrong here?)

import java.util.Date;

public class Test {
    public static void main(String[] args) {
        Date before = new Date();
        for (int j = 1; j < 50000000; j++) {
            int a = 1 ;
            for (int i = 0; i< 10; i++){
                a *=2;
            }
        }
        Date after = new Date();
        System.out.println("Multiplying " + (after.getTime()-before.getTime()) + " milliseconds");
        before = new Date();
        for (int j = 1; j < 50000000; j++) {
            int a = 1 ;
            for (int i = 0; i< 10; i++){
                a = a << 1;
            }
        }
        after = new Date();
        System.out.println("Shifting " + (after.getTime()-before.getTime()) + " milliseconds");
    }
}

The results are:

Multiplying 639 milliseconds
Shifting 718 milliseconds

查看更多
零度萤火
5楼-- · 2019-01-01 14:01

On computers I tested, integer divisions are 4 to 10 times slower than other operations.

When compilers may replace divisions by multiples of 2 and make you see no difference, divisions by not multiples of 2 are significantly slower.

For example, I have a (graphics) program with many many many divisions by 255. Actually my computation is :

r = (((top.R - bottom.R) * alpha + (bottom.R * 255)) * 0x8081) >> 23;

I can ensure that it is a lot faster than my previous computation :

r = ((top.R - bottom.R) * alpha + (bottom.R * 255)) / 255;

so no, compilers cannot do all the tricks of optimization.

查看更多
刘海飞了
6楼-- · 2019-01-01 14:03

It is hardware dependent. If we are talking micro-controller or i386, then shifting might be faster but, as several answers state, your compiler will usually do the optimization for you.

On modern (Pentium Pro and beyond) hardware the pipelining makes this totally irrelevant and straying from the beaten path usually means you loose a lot more optimizations than you can gain.

Micro optimizations are not only a waste of your time, they are also extremely difficult to get right.

查看更多
何处买醉
7楼-- · 2019-01-01 14:04

Note that shifting down and division will (in Java, certainly) give different results for negative, odd numbers.

int a = -7;
System.out.println("Shift: "+(a >> 1));
System.out.println("Div:   "+(a / 2));

Prints:

Shift: -4
Div:   -3

Since Java doesn't have any unsigned numbers it's not really possible for a Java compiler to optimise this.

查看更多
登录 后发表回答