阅读问题后Why is processing a sorted array faster than an unsorted array? 我们曾尝试将变量设置为 volatile (我预计,当我使用 volatile 时,它的工作速度一定会更慢,但它的工作速度更快) 这是我的代码,没有 volatile :(它的工作时间约为 11 秒。)
import java.util.Arrays;
import java.util.Random;
public class GGGG {
public static void main(String[] args) {
int arraySize = 32768;
int data[];
data = new int[arraySize];
Random rnd = new Random(0);
for (int c = 0; c < arraySize; ++c) {
data[c] = rnd.nextInt() % 256;
}
Arrays.sort(data);
long start = System.nanoTime();
long sum = 0;
for (int i = 0; i < 200000; ++i) {
for (int c = 0; c < arraySize; ++c) {
if (data[c] >= 128) {
sum += data[c];
}
}
}
System.out.println((System.nanoTime() - start) / 1000000000.0);
System.out.println("sum = " + sum);
System.out.println("=========================");
}
输出是:
10.876173341
sum = 310368400000
=========================
这是当我使用 arraySize 和数据变量作为 volatile 时,它工作了大约 7 秒:
import java.util.Arrays;
import java.util.Random;
public class GGGG {
static volatile int arraySize = 32768;
static volatile int data[];
public static void main(String[] args) {
data = new int[arraySize];
Random rnd = new Random(0);
for (int c = 0; c < arraySize; ++c) {
data[c] = rnd.nextInt() % 256;
}
Arrays.sort(data);
long start = System.nanoTime();
long sum = 0;
for (int i = 0; i < 200000; ++i) {
for (int c = 0; c < arraySize; ++c) {
if (data[c] >= 128) {
sum += data[c];
}
}
}
System.out.println((System.nanoTime() - start) / 1000000000.0);
System.out.println("sum = " + sum);
System.out.println("=========================");
}
volatile 的输出是:
6.776267265
sum = 310368400000
=========================
我本以为 volatility 会减慢进程,但它运行得更快。发生什么事了?
最佳答案
我将仅列出您的代码的两个主要问题:
- 没有预热;
- 一切都发生在
main
方法中,因此 JIT 编译的代码只能通过栈上替换来运行。
使用 jmh
工具重做您的案例,我得到的时间与预期一致。
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 3, time = 2)
@Measurement(iterations = 5, time = 3)
@State(Scope.Thread)
@Threads(1)
@Fork(2)
public class Writing
{
static final int ARRAY_SIZE = 32768;
int data[] = new int[ARRAY_SIZE];
volatile int volatileData[] = new int[ARRAY_SIZE];
@Setup public void setup() {
Random rnd = new Random(0);
for (int c = 0; c < ARRAY_SIZE; ++c) {
data[c] = rnd.nextInt() % 256;
volatileData[c] = rnd.nextInt() % 256;
}
Arrays.sort(data);
System.arraycopy(data, 0, volatileData, 0, ARRAY_SIZE);
}
@GenerateMicroBenchmark
public long sum() {
long sum = 0;
for (int c = 0; c < ARRAY_SIZE; ++c) if (data[c] >= 128) sum += data[c];
return sum;
}
@GenerateMicroBenchmark
public long volatileSum() {
long sum = 0;
for (int c = 0; c < ARRAY_SIZE; ++c) if (volatileData[c] >= 128) sum += volatileData[c];
return sum;
}
}
结果如下:
Benchmark Mode Samples Mean Mean error Units
sum avgt 10 21.956 0.221 us/op
volatileSum avgt 10 40.561 0.264 us/op
关于java - 为什么 volatile 比非 volatile 工作得更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21598558/