减少了java中无阵列边界检查的阵列访问时间

减少了java中无阵列边界检查的阵列访问时间,java,arrays,performance,Java,Arrays,Performance,嗯。我对微基准的事情估计错误。如果你没有多余的时间,请不要阅读 而不是 double[] my_array=new array[1000000];double blabla=0; for(int i=0;i<1000000;i++) { my_array[i]=Math.sqrt(i);//init } for(int i=0;i<1000000;i++) { blabla+=my_array[i];//array access time is 3.7ms per 1M o

嗯。我对微基准的事情估计错误。如果你没有多余的时间,请不要阅读

而不是

double[] my_array=new array[1000000];double blabla=0;
for(int i=0;i<1000000;i++)
{
  my_array[i]=Math.sqrt(i);//init
}

for(int i=0;i<1000000;i++)
{
  blabla+=my_array[i];//array access time is 3.7ms per 1M operation
}
double[]my_数组=新数组[1000000];双blabla=0;

对于(int i=0;i再次查看代码,我可以看到在第一个循环中,您添加了1m个不同的元素。在第二个示例中,您添加了1m次相同的
static
元素


微基准测试的一个常见问题是,您执行测试的顺序会影响结果

例如,如果您有两个循环,第一个循环最初不会编译为本机代码。但是,一段时间后,整个方法将被编译,循环将运行得更快

然后运行第二个循环,发现它是

  • 更快,因为它从一开始就得到了优化。(对于简单循环)
  • 速度慢得多,因为它在没有任何运行时指标的情况下进行了优化。(对于复杂循环)
您需要将每个循环放在一个单独的方法中,并交替运行测试若干次,以获得可复制的结果



在第一种情况下,循环运行一段时间后才会进行优化。在第二种情况下,循环启动时可能已经编译好了。

很容易解释这一差异:

  • 基本阵列的内存占用为1M*8字节=8MB
  • 该类数组的内存占用为1M*4字节=4MB,全部指向同一个实例(假设为32位VM或压缩引用64位VM)

将不同的对象放入类数组中,您将看到基元数组的性能更好。您目前正在将桔子与苹果进行比较。

您的基准测试和上面的评估存在几个问题。首先,您的代码没有按图所示编译。其次,您的基准测试时间(即几毫秒)对于今天的高速处理器来说,它们的时间太短了,没有任何统计价值。第三,你将苹果和橙子进行比较(如上所述)。也就是说,你在为两个完全不同的用例计时:一个静态用例和一百万个变量

我修复了您的代码,并在i7-2620m上运行了几次,每次重复10000 x 1000000次。所有结果都在+/-1%范围内,这对于本次讨论来说已经足够好了。然后,为了比较它们的性能,我选择了所有运行中最快的一次

上面,您声称第二个用例比第一个用例“低25%”,这是非常不准确的

为了进行“静态”与“可变”性能比较,我改变了第一个基准,添加了999999平方根,就像第二个基准一样。第二个用例的差异只有4.63%

为了进行阵列访问性能比较,我将第二个用例更改为“非静态”变量。与第一个用例(原始阵列访问)相比,差异约为68.2%,这意味着第一种方式比第二种方式快得多


(我从事绩效衡量和评估已有25年之久,请随时向我询问更多有关微观基准的信息。)

所有结果都是从0到20的循环。第一次运行正在预热。结果来自已预热的位置。我怀疑其原因是
元素
是静态的,因此只有一个,而不是一百万个。
public final static class my_class
{
 public static double element=0;
 my_class(double elementz)
 {
 element=elementz;
 }
}

my_class[] class_z=new my_class[1000000];
for(int i=0;i<1000000;i++)
{
class_z[i]=new my_class(Math.sqrt(i)); //instantiating array elements for later use(random-access)
}

double blabla=0;

for(int i=0;i<1000000;i++)
{
blabla+=class_z[i].element; // array access time 2.7 ms per 1M operations.
}
}