gpt4 book ai didi

java - 设置/返回数组的首选方式

转载 作者:搜寻专家 更新时间:2023-10-31 19:57:13 28 4
gpt4 key购买 nike

请比较两种设置/返回数组的方式:

static public float[] test_arr_speeds_1( int a ) {
return new float[]{ a, a + 1, a + 2, a + 3, a + 4, a + 5,
a + 6, a + 7, a + 8, a + 9 };
} // or e.g. field = new float... in method

static public float[] test_arr_speeds_2( int a ) {
float[] ret = new float[10];
ret[0] = a;
ret[1] = a + 1;
ret[2] = a + 2;
ret[3] = a + 3;
ret[4] = a + 4;
ret[5] = a + 5;
ret[6] = a + 6;
ret[7] = a + 7;
ret[8] = a + 8;
ret[9] = a + 9;
return ret;
} // or e.g. field[0] = ... in method

两者都生成不同的字节码,并且都可以反编译到它们以前的状态。通过探查器检查执行时间后(100M 次迭代,无偏见,不同的环境),_1 方法的时间约为。 _2 时间的 4/3,即使两者都创建了一个新数组并将每个字段都设置为给定值。大多数时候时间可以忽略不计,但这仍然让我感到烦恼 - 为什么 _1 明显变慢?谁能以一种合理的、JVM 支持的方式向我检查/确认/解释它?

最佳答案

这是字节码之间的区别(仅针对前两项)。第一种方法:

bipush  10
newarray float //creating an array with reference on operand stack

dup
iconst_0
iload_0
i2f
fastore //setting first element

dup
iconst_1
iload_0
iconst_1
iadd
i2f
fastore //setting second element

//...
areturn //returning the top of the operand stack

第二种方法:

bipush  10
newarray float
astore_1 //creating an array and storing it in local variable

aload_1
iconst_0
iload_0
i2f
fastore //setting first element

aload_1
iconst_1
iload_0
iconst_1
iadd
i2f
fastore //setting second element

//...
aload_1
areturn

正如您所看到的,唯一的区别是在第一种情况下数组引用保存在操作数堆栈中(这就是为什么 dup 出现这么多次 - 以避免在 fastore 之后丢失对数组的引用)而在在第二种情况下,数组引用保存在普通 堆栈中(其中保存方法参数和局部变量)。在这种情况下,必须始终读取引用 ( aload_1 ),因为 fastore要求 arrayref 在操作数堆栈上。

我们不应该基于这个字节码做出假设——毕竟它被 翻译成了 CPU 指令。在这两种情况下,数组引用很可能都存储在 CPU 寄存器之一中。否则性能差异会很大。

如果您可以测量差异并且您正在执行低级优化 - 选择速度更快的版本。但我怀疑区别是“可移植的”(取决于体系结构和 JVM 版本/实现,您会观察到不同的计时行为)。话虽这么说 - 我会选择更具可读性的版本,而不是恰好在您的计算机上速度更快的版本。

关于java - 设置/返回数组的首选方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10870194/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com