测试简介
测试代码如下所示,通过三层循环做了100亿次操作。操作的核心语句是:r += data[(i + j * k) % data.length];
这里引用了三个循环控制变量,以保证编译器不进行优化(注:如果每次循环一样,编译器可能将其中一次循环的结果保存,从而大大加快循环速度)。
public class CPUSpeedTest {
public static void main(String[] args) throws Exception {
long r = 0;
long t1 = System.currentTimeMillis();
int[] data = new int[1000];
for(int i = 0; i < data.length; i++)
data[i] = i;
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 10000; j++) {
for (int k = 0; k < 10000; k++) {
r += data[(i + j * k) % data.length];
}
}
}
long t2 = System.currentTimeMillis();
System.out.println("r = " + r + ", time(ms) = " + (t2 - t1));
}
}
运行结果
运行环境为 i5 9600K+32G DDR4 2666,以下为结果。
D:\Java>java CPUSpeedTest
r = 4984020000000, time(ms) = 20803
D:\Java>java CPUSpeedTest
r = 4984020000000, time(ms) = 20903
D:\Java>java CPUSpeedTest
r = 4984020000000, time(ms) = 20884
结果分析
平均时间约20.86秒。
仅考虑k层的每次运算就有以下内容:
- 整型乘法x1: i
*
j - 整型加法x2: k
++
和 i+
(j*k) - 浮点加法x1: r
+=
data[(i + j * k) % data.length] - 求余操作x1: data[(i + j * k)
%
data.length] - 数组访问x1: data
[(i + j * k) % data.length]
- 逻辑判断x1:k
<
10000
由于 i 层数量是100, j 层的操作量是1001000 都远小于 k 层,所以忽略不计。因此,总共有约有6100亿次数据操作。10亿次操作用时20.86秒,相当于每秒完成4.79亿次循环运算。根据另外一个测试,不加数组访问的性能是当前的一倍,可以得到一次数据访问,约相当于6次计算或逻辑判断操作。所以每秒可以进行的数组访问次数约为6亿次。