设置/返回数组preferred方式 [英] preferred way of setting/returning arrays

查看:138
本文介绍了设置/返回数组preferred方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请设置比较两种方法/返回一个数组:

Please compare two ways of setting/returning an array:

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

这两种截然不同的生成字节codeS和既可以反编译到原来的状态。检查通过探查的执行时间(100M迭代,公正的,不同的周围)后,_1方法​​的时间大约为4/3的_2的时间,即使两个创建一个新的数组和两个每字段设置为一个给定值。该时间可以忽略不计的大部分时间,但仍我的错误 - 为什么_1明显慢?任何人都可以查询/确认/在一个合理的,JVM支持的方式解释给我吗?

Both generate distinct bytecodes and both can be decompiled to their former state. After checking the execution times via profiler (100M iterations, unbiased, different environs), the time of _1 method is approx. 4/3 the time of _2, even though both create a new array and both set every field to a given value. The times are negligible most of the time, but this still bugs me - why is _1 visibly slower? Can anybody check/confirm/explain it to me in a reasonable, JVM-supported way?

推荐答案

下面是(仅适用于前两个项目)字节code之间的区别。第一种方法:

Here is the difference between bytecode (only for first two items). First method:

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 要求数组引用是对操作数堆叠。

As you can see the only difference is that the array reference is kept on operand stack in the first scenario (that's why dup appears so many times - to avoid loosing a reference to an array after fastore) while in the second scenario the array reference is kept on normal stack (where method arguments and local variables are kept). In this scenario the reference must be read all the time (aload_1) because fastore requires arrayref to be on on the operand stack.

在此基础上字节code我们不应该做假设 - 毕竟它是由的 JIT 以及最有可能在两种情况下,数组引用被存储在CPU寄存器中的一个。否则,性能差异将是巨大的。

We shouldn't make assumptions based on this bytecode - after all it is translated to CPU instructions by jit and most likely in both cases array reference is stored in one of the CPU registers. Otherwise the performance difference would be huge.

如果你可以测量的差异,你正在做这样的低级别的优化 - 挑选速度更快的版本。但我怀疑不同的是便携式(依赖于架构和JVM版本/实现你会观察不同的时序行为)。话虽这么说 - 我会去更可读的版本,而不是恰好是你的电脑快上一

If you can measure the difference and you are doing so low-level optimizations - pick the version that is faster. But I doubt the difference is "portable" (depending on the architecture and JVM version/implementation you will observer different timing behaviour). That being said - I would go for more readable version, rather than the one that happens to be faster on your computer.

这篇关于设置/返回数组preferred方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆