【发布时间】:2013-01-31 22:04:26
【问题描述】:
我在 java 中对一个长数组执行了一个简短的基准测试,结果很奇怪。似乎带有随机写入的顺序读取比带有顺序写入的随机读取要快 - 一半的时间。有人知道为什么吗??
这里有两种方法,在顺序读取时随机写入一些longs的数组(使用-Xmx2G左右运行),在随机写入时顺序读取:
import java.util.Random;
public class Scratch {
static Random random = new Random();
static long[] arr = new long[100000000];
static void seqReadRandWrite() {
for(int i=0;i<arr.length;i++) {
int at = random.nextInt(arr.length);
arr[at] = arr[i];
}
}
static void seqWriteRandRead() {
for(int i=0;i<arr.length;i++) {
int at = random.nextInt(arr.length);
arr[i] = arr[at];
}
}
public static void main(String[] args) throws Exception {
seqWriteRandRead(); // warm up
long nanos = System.nanoTime();
seqReadRandWrite();
System.out.println("Time: " + (System.nanoTime()-nanos) + "ns");
nanos = System.nanoTime();
seqWriteRandRead();
System.out.println("Time: " + (System.nanoTime()-nanos) + "ns");
}
}
我笔记本上的结果是
时间:2774662168ns
时间:6059499068ns
这意味着随机写入的速度是读取速度的两倍……还是?我的笔记本坏了吗?
ps.:这并不声称是一个基准,尽管有关基准的链接建议中的大部分要点都已涵盖。即使我多次运行已经 200,000,000 次操作,结果仍然保持不变。似乎(似乎!)将内存从随机位置移动到顺序块比将内存从顺序位置移动到随机块慢,至少在这种大小的内存和上述执行方式的情况下。我想知道为什么?
【问题讨论】:
-
你为什么不预热
seqReadRandWrite()方法呢?你确定一次调用就足以调用 JIT 编译器吗? -
那只是为了记忆..试试看,没区别
-
我的 WAG 会优化顺序读取,因为这通常在编程中完成。这就是第一个算法更快的原因。
-
@MiserableVariable - 我只是出于好奇做了那个测试 - 顺序读/写以几乎相同的速度运行(如预期的那样)。但随机读取似乎比随机写入慢两倍。我确实相信这是内存缓存的影响。
-
'短基准' => 无效基准。
标签: java performance memory