5

为什么组j=k*lm=n*o有不同的表现,而前3组有相同的?

int a = 42;
int b = 42;
int c = 42;

Integer d = 42;
int e = 42;
int f = 42;

int g = 42;
Integer h = 42;
int i = 42;

int j = 42;
int k = 42;
Integer l = 42;

Integer m = 42;
Integer n = 42;
Integer o = 42;

for(int z = 0; z < 1000000000; z++){
    // c = a*b; // 630 ms
    // f = d*e; // 630 ms
    // i = g*h; // 630 ms
    // l = j*k; // 6000 ms
    // o = m*n; // 6400 ms
}
4

7 回答 7

6

你有一个没有做任何有用的循环。因此,JIT 可能需要一些时间来检测这一点并消除循环。在前四个示例中,代码取时钟周期的一小部分的平均值。这是一个强有力的暗示,表明循环已被优化掉,您实际上正在测量检测和替换循环需要多长时间,

在后面的示例中,循环没有被优化掉,因为 JIT 没有消除循环中的某些内容。我怀疑这是对象分配,Integer-verbosegc显示没有创建对象。

在我的机器上,循环大约需要 1.9 ns 或大约 6 个时钟周期,这非常快,所以我不确定还剩下什么需要这么多时间..

于 2013-01-28T08:27:27.167 回答
4

在一个循环中创建一个新对象总是有代价的。在最后两个示例中,您在循环中创建了新的 Integer 对象,这具有很高的性能成本。基元存储在堆栈中,对象存储在堆中。将某些东西放入堆栈比放入堆中便宜。

于 2013-01-28T08:21:00.447 回答
4

基本上这就是 JVM 内部发生的事情,这会导致性能问题。

c = a*b; // 630  ms -> No boxing and unboxing
f = d*e; // 630  ms -> Unboxing d
i = g*h; // 630  ms -> Unboxing h
l = j*k; // 6000 ms -> Creates a new Integer object L, and assign J * K to L
o = m*n; // 6400 ms -> Creates a new Integer object 0, unbox m and n for calculation and assign m * n to o

换句话说

l = j*k;// 6000 ms 相当于下面的代码

temp = j*k;
Integer l = new Integer(temp); 

o = m*n; // 6400 ms 相当于下面的代码

temp = j.intValue() * k.intValue();
Integer l = new Integer(temp); 

您的最后两个语句将围绕1000000000(循环计数)不必要Integer的对象创建。这显然是一个性能障碍。

于 2013-01-28T08:32:36.370 回答
1
  1. 整数自动框有一个小缓存
  2. 创建一个对象会花费大量时间

检查这个:java.lang.Integer.IntegerCache

于 2013-01-28T08:24:43.617 回答
0

可能是因为l = j * k需要将 int 装箱为 Integer,c = a * b而不需要。VM 还可以优化循环,理解执行一次迭代将导致与执行 10 亿次相同的结果。当心简单的微基准。

于 2013-01-28T08:22:38.743 回答
0
m = n*o  ==> Integer = Integer * Integer 

尽管:

l = j*k ==> Integer = int * int // Integer is an object so autoboxing costs some performance here.
于 2013-01-28T08:23:05.693 回答
0

创建对象有开销(或者,从其他评论看来,可能是在创建对象时,循环无法优化,因为它内部没有做任何事情)。

int = int * int

不涉及对象。

int = Integer * int或者int = int * Integer

Integer 的 int 成员与 int 相乘,不需要创建任何对象。

Integer = int * int

需要从结果中创建一个 Integer 对象(慢)。

Integer = Integer * Integer

两个 Integer 的 int 成员相乘,但随后需要从结果中创建一个 Integer 对象(慢)。

于 2013-01-28T08:27:07.833 回答