使用按位运算或数字文字初始化值是否更快?

时间:2015-07-15 14:35:20

标签: java hashmap bitwise-operators bit-shift

我正在浏览HashMap的源代码。我看到了类似的东西   static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16.我想知道为什么他们使用移位运算符。这会加快计算速度吗?所以我查找了这三个操作之间的byte差异:

int DEFAULT_INITIAL_CAPACITY =  0x10;
L0
    LINENUMBER 52 L0
    BIPUSH 16
    ISTORE 1



int DEFAULT_INITIAL_CAPACITY1 =  1 << 4;
  L1
    LINENUMBER 54 L1
    BIPUSH 16
    ISTORE 2

int test = 16;
 L2
    LINENUMBER 56 L2
    BIPUSH 16
    ISTORE 3

值的初始化方式是否重要?

5 个答案:

答案 0 :(得分:6)

信不信由你,它实际上是关于可读性的。表达式1 << 4肯定不会比表达式16更快地进行评估。另外,无论表达式是什么,都会在编译时进行评估。

使用移位表示的关键是它是表达圆二进制数的更自然的方式。初始容量的不变量以及哈希表实现中的许多其他东西,它必须是纯粹的2的幂。这更直接地与表达式1 << n(相当于2 n )比十进制表示更直接地传达,特别是当您进入更高的n值时(例如高于{1}}例如,16)。

答案 1 :(得分:4)

从速度的角度来看,这可能不是一个优势。但是,看起来HashMap的capacity始终是2的幂(甚至指定构造函数中的容量导致调用Collections.roundUpToPowerOfTwo(capacity)),因此以{{1 << x的形式表示它即使您要更改x,也可以轻松确保此限制。如果您不了解限制,其他形式在更改时会更容易搞乱

答案 2 :(得分:4)

正如您自己想象的那样,字节代码对于常数16或1&lt;&lt; 4.在这种特殊情况下,我认为这只是一个可读性的问题:强调初始容量应该是2的幂(通过向左移动1,你只能获得2的幂)。这就是我在HashMap的源代码中所拥有的:

/**
 * The default initial capacity - MUST be a power of two.
 */
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

答案 3 :(得分:2)

下面是您问题中描述的三种初始化方法的定时测试。

public static void main(String[] args) {

    long time = System.currentTimeMillis();
    int test = 0;
    for(int i = 0; i < 100000; i++){
        test = 16;
    }

    System.out.println((System.currentTimeMillis() - time) + " : " + test);

    time = System.currentTimeMillis();
    int test2 = 0;
    for(int i = 0; i < 100000; i++){
        test2 = 1 << 4;
    }

    System.out.println((System.currentTimeMillis() - time) + " : " + test2);

    time = System.currentTimeMillis();
    int test3 = 0;
    for(int i = 0; i < 100000; i++){
        test3 = 0x10;
    }

    System.out.println((System.currentTimeMillis() - time) + " : " + test3);
}

运行此产生

  

2:16

     

2:16

     

2:16

每次执行时每次+或 - 5毫秒。这表明该值初始化的方式几乎无关紧要。

<强>结论

使用哪种方法初始化值没有程序化差异。

似乎使用1 << 4超过160x10的唯一原因是强制初始值为2的幂。

答案 4 :(得分:2)

基本上,移位运算符用于处理位,比使用+, -

等其他运算符更快

例 - 将CPU加工的两个数相乘,它将在内部执行乘法,用加法和减法代替它,它只是移位和执行AND,OR,NOT等操作。

因此,如果您直接使用位,则意味着您正在完成必须由CPU完成大量处理后的工作。

另见: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html