java.util.Random 使计算速度提高 100 倍?
java.util.Random makes 100 times faster computation?
我完全无话可说,我不知道发生了什么......
//import java.util.Random;
public class TestInProgress {
public static void main(String[] args) {
long start, end;
long average;
// Random random= new Random();
for(int j=0; j<5; j++) {
average= 0L;
for(int i=0; i<100; i++) {
start= System.nanoTime();
double temp= fastComputeSigm(0.0);
end= System.nanoTime();
average+= (end - start);
}
average= average/ 100L;
System.out.println("AVERAGE FASTCOMPUTE: "+average);
average= 0L;
for(int i=0; i<100; i++) {
start= System.nanoTime();
double temp= Math.exp(0.0)/(1.0 + Math.exp(0.0));
end= System.nanoTime();
average+= (end - start);
}
average= average / 100L;
System.out.println("AVERAGE SIGMOID: "+average);
}
}
static double fastComputeSigm(double value) {
return 0.0;
}
}
最意外的是输出:
AVERAGE FASTCOMPUTE: 98 AVERAGE SIGMOID: 38625 AVERAGE FASTCOMPUTE:
106 AVERAGE SIGMOID: 65 AVERAGE FASTCOMPUTE: 299 AVERAGE SIGMOID: 201
AVERAGE FASTCOMPUTE: 36 AVERAGE SIGMOID: 65 AVERAGE FASTCOMPUTE: 53
AVERAGE SIGMOID: 57
看到了吗?我取消注释 Random (及其导入)
你会期待什么?输出:
AVERAGE FASTCOMPUTE: 90 AVERAGE SIGMOID: 324 AVERAGE FASTCOMPUTE: 131
AVERAGE SIGMOID: 73 AVERAGE FASTCOMPUTE: 217 AVERAGE SIGMOID: 36
AVERAGE FASTCOMPUTE: 53 AVERAGE SIGMOID: 12 AVERAGE FASTCOMPUTE: 53
AVERAGE SIGMOID: 69
我在 eclipse Oxygen.3a 版本 (4.7.3a) 上试过这个
我正在使用 java 10.0.2
我的电脑有英特尔酷睿 i5-7300HQ
带有这些高速缓存:L1 256、L2 1024、L3 6M
我 运行 在 windows 10
注意:我尝试用 j<1,2,3,... 进行 forloop 几次都没有帮助第一个 sigmoid 总是有荒谬的时间长度
编辑:尝试使用 windows 命令行(javac 和 java)启动它,结果相同
总的来说,指出微基准测试的技巧的评论是正确的,您应该使用 JMH。在这种特殊情况下,您的计时/基准测试代码似乎引入了最初不存在的延迟。
这是您代码的压缩版本,它表明问题不是由使用 Random
而是由使用 System.nanoTime()
触发的(Random()
在内部调用)
public static void main(String[] args) {
long start, end, average;
double temp = 0;
// start = System.nanoTime();
average = 0L;
for (int i = 0; i < 100; i++) {
start = System.nanoTime();
temp += Math.exp(0.0) / (1.0 + Math.exp(0.0));
end = System.nanoTime();
average += (end - start);
// System.out.println(i + " " + (end - start));
}
System.out.println("AVERAGE: " + (average / 100));
System.out.println("temp: " + temp);
}
当我取消注释 start = System.nanoTime()
时,我观察到 x100 加速 - 此时重要的是要记住这里的单位是 nanoseconds
所以我们 非常 对运行时在后台所做的任何事情都很敏感。如果您取消注释 System.out.println(i + " " + (end - start));
,您会偶尔看到 打嗝 ,这是导致整个速度下降的原因。虽然追查 hiccup 的原因可能很有趣,但以下版本的代码表明这是由于测量而不是核心功能引起的,因此您可能需要确保这是您想花时间在 [1]:
上的事情
public static void main(String[] args) {
double temp = 0;
long start = System.nanoTime();
for (int i = 0; i < 100; i++) {
temp += Math.exp(0.0) / (1.0 + Math.exp(0.0));
}
System.out.println("AVERAGE: " + ((System.nanoTime() - start) / 100));
System.out.println("temp: " + temp);
}
此处的 AVERAGE 值与之前的版本相似,start = System.nanoTime()
未注释。
[1] 如果您有兴趣深入研究此特定行为,请尝试在 运行 禁用编译器的 -Xint
VM 选项时为您的测试计时。
我完全无话可说,我不知道发生了什么......
//import java.util.Random;
public class TestInProgress {
public static void main(String[] args) {
long start, end;
long average;
// Random random= new Random();
for(int j=0; j<5; j++) {
average= 0L;
for(int i=0; i<100; i++) {
start= System.nanoTime();
double temp= fastComputeSigm(0.0);
end= System.nanoTime();
average+= (end - start);
}
average= average/ 100L;
System.out.println("AVERAGE FASTCOMPUTE: "+average);
average= 0L;
for(int i=0; i<100; i++) {
start= System.nanoTime();
double temp= Math.exp(0.0)/(1.0 + Math.exp(0.0));
end= System.nanoTime();
average+= (end - start);
}
average= average / 100L;
System.out.println("AVERAGE SIGMOID: "+average);
}
}
static double fastComputeSigm(double value) {
return 0.0;
}
}
最意外的是输出:
AVERAGE FASTCOMPUTE: 98 AVERAGE SIGMOID: 38625 AVERAGE FASTCOMPUTE: 106 AVERAGE SIGMOID: 65 AVERAGE FASTCOMPUTE: 299 AVERAGE SIGMOID: 201 AVERAGE FASTCOMPUTE: 36 AVERAGE SIGMOID: 65 AVERAGE FASTCOMPUTE: 53 AVERAGE SIGMOID: 57
看到了吗?我取消注释 Random (及其导入) 你会期待什么?输出:
AVERAGE FASTCOMPUTE: 90 AVERAGE SIGMOID: 324 AVERAGE FASTCOMPUTE: 131 AVERAGE SIGMOID: 73 AVERAGE FASTCOMPUTE: 217 AVERAGE SIGMOID: 36 AVERAGE FASTCOMPUTE: 53 AVERAGE SIGMOID: 12 AVERAGE FASTCOMPUTE: 53 AVERAGE SIGMOID: 69
我在 eclipse Oxygen.3a 版本 (4.7.3a) 上试过这个 我正在使用 java 10.0.2 我的电脑有英特尔酷睿 i5-7300HQ 带有这些高速缓存:L1 256、L2 1024、L3 6M 我 运行 在 windows 10
注意:我尝试用 j<1,2,3,... 进行 forloop 几次都没有帮助第一个 sigmoid 总是有荒谬的时间长度
编辑:尝试使用 windows 命令行(javac 和 java)启动它,结果相同
总的来说,指出微基准测试的技巧的评论是正确的,您应该使用 JMH。在这种特殊情况下,您的计时/基准测试代码似乎引入了最初不存在的延迟。
这是您代码的压缩版本,它表明问题不是由使用 Random
而是由使用 System.nanoTime()
触发的(Random()
在内部调用)
public static void main(String[] args) {
long start, end, average;
double temp = 0;
// start = System.nanoTime();
average = 0L;
for (int i = 0; i < 100; i++) {
start = System.nanoTime();
temp += Math.exp(0.0) / (1.0 + Math.exp(0.0));
end = System.nanoTime();
average += (end - start);
// System.out.println(i + " " + (end - start));
}
System.out.println("AVERAGE: " + (average / 100));
System.out.println("temp: " + temp);
}
当我取消注释 start = System.nanoTime()
时,我观察到 x100 加速 - 此时重要的是要记住这里的单位是 nanoseconds
所以我们 非常 对运行时在后台所做的任何事情都很敏感。如果您取消注释 System.out.println(i + " " + (end - start));
,您会偶尔看到 打嗝 ,这是导致整个速度下降的原因。虽然追查 hiccup 的原因可能很有趣,但以下版本的代码表明这是由于测量而不是核心功能引起的,因此您可能需要确保这是您想花时间在 [1]:
public static void main(String[] args) {
double temp = 0;
long start = System.nanoTime();
for (int i = 0; i < 100; i++) {
temp += Math.exp(0.0) / (1.0 + Math.exp(0.0));
}
System.out.println("AVERAGE: " + ((System.nanoTime() - start) / 100));
System.out.println("temp: " + temp);
}
此处的 AVERAGE 值与之前的版本相似,start = System.nanoTime()
未注释。
[1] 如果您有兴趣深入研究此特定行为,请尝试在 运行 禁用编译器的 -Xint
VM 选项时为您的测试计时。