为什么添加try块可以加快程序速度?
为什么添加try块可以加快程序速度?
我正在使用以下代码测试 try 块的速度慢。出乎意料的是,try 块反而让它变快了。为什么?
public class Test { int value; public int getValue() { return value; } public void reset() { value = 0; } // Calculates without exception public void method1(int i) { value = ((value + i) / i) << 1; // Will never be true if ((i & 0xFFFFFFF) == 1000000000) { System.out.println("You'll never see this!"); } } public static void main(String[] args) { int i; long l; Test t = new Test(); l = System.currentTimeMillis(); t.reset(); for (i = 1; i < 100000000; i++) { t.method1(i); } l = System.currentTimeMillis() - l; System.out.println("method1 took " + l + " ms, result was " + t.getValue()); // using a try block l = System.currentTimeMillis(); t.reset(); for (i = 1; i < 100000000; i++) { try { t.method1(i); } catch (Exception e) { } } l = System.currentTimeMillis() - l; System.out.println("method1 with try block took " + l + " ms, result was " + t.getValue()); } }
我的计算机正在运行64位的Windows 7和64位的JDK7。我得到了以下结果:
method1 took 914 ms, result was 2 method1 with try block took 789 ms, result was 2
我已经运行了很多次代码,每次都几乎得到相同的结果。
更新:
在 MacBook Pro 上运行测试十次的结果如下,Java 6。try-catch 使方法更快,与 Windows 上相同。
method1 took 895 ms, result was 2 method1 with try block took 783 ms, result was 2 -------------------------------------------------- method1 took 943 ms, result was 2 method1 with try block took 803 ms, result was 2 -------------------------------------------------- method1 took 867 ms, result was 2 method1 with try block took 745 ms, result was 2 -------------------------------------------------- method1 took 856 ms, result was 2 method1 with try block took 744 ms, result was 2 -------------------------------------------------- method1 took 862 ms, result was 2 method1 with try block took 744 ms, result was 2 -------------------------------------------------- method1 took 859 ms, result was 2 method1 with try block took 765 ms, result was 2 -------------------------------------------------- method1 took 937 ms, result was 2 method1 with try block took 767 ms, result was 2 -------------------------------------------------- method1 took 861 ms, result was 2 method1 with try block took 744 ms, result was 2 -------------------------------------------------- method1 took 858 ms, result was 2 method1 with try block took 744 ms, result was 2 -------------------------------------------------- method1 took 858 ms, result was 2 method1 with try block took 749 ms, result was 2
admin 更改状态以发布 2023年5月21日
我用 Caliper Microbenchmark 尝试了一下,但实际上我真的看不出有什么区别。
下面是代码:
public class TryCatchBenchmark extends SimpleBenchmark { private int value; public void setUp() { value = 0; } // Calculates without exception public void method1(int i) { value = ((value + i) / i) << 1; // Will never be true if ((i & 0xFFFFFFF) == 1000000000) { System.out.println("You'll never see this!"); } } public void timeWithoutTryCatch(int reps) { for (int i = 1; i < reps; i++) { this.method1(i); } } public void timeWithTryCatch(int reps) { for (int i = 1; i < reps; i++) { try { this.method1(i); } catch (Exception ignore) { } } } public static void main(String[] args) { new Runner().run(TryCatchBenchmark.class.getName()); } }
这是结果:
0% 场景{vm=java, trial=0, benchmark=WithoutTryCatch} 8,23 ns;σ=0,03 ns @ 3 次试验 50% 场景{vm=java, trial=0, benchmark=WithTryCatch} 8,13 ns;σ=0,03 ns @ 3 次试验 benchmark ns linear runtime WithoutTryCatch 8,23 ============================== WithTryCatch 8,13 =============================
如果我交换一下函数的顺序(让它们按相反的顺序运行),结果是:
0% 场景{vm=java, trial=0, benchmark=WithTryCatch} 8,21 ns;σ=0,05 ns @ 3 次试验 50% 场景{vm=java, trial=0, benchmark=WithoutTryCatch} 8,14 ns;σ=0,03 ns @ 3 次试验 benchmark ns linear runtime WithTryCatch 8,21 ============================== WithoutTryCatch 8,14 =============================
我认为它们基本上是一样的。
当一个方法中有多个长时间运行的循环时,其中一个循环可以触发整个方法的优化,对第二个循环产生无法预测的结果。避免这种情况的一种方法是:
- 为每个循环提供自己的方法
- 多次运行测试以检查结果是否可重复
- 运行测试2-10秒钟。
你会看到一些变化,有时结果不确定,即变异程度高于差异。
public class Test { int value; public int getValue() { return value; } public void reset() { value = 0; } // Calculates without exception public void method1(int i) { value = ((value + i) / i) << 1; // Will never be true if ((i & 0xFFFFFFF) == 1000000000) { System.out.println("You'll never see this!"); } } public static void main(String[] args) { Test t = new Test(); for (int i = 0; i < 5; i++) { testWithTryCatch(t); testWithoutTryCatch(t); } } private static void testWithoutTryCatch(Test t) { t.reset(); long l = System.currentTimeMillis(); for (int j = 0; j < 10; j++) for (int i = 1; i <= 100000000; i++) t.method1(i); l = System.currentTimeMillis() - l; System.out.println("without try/catch method1 took " + l + " ms, result was " + t.getValue()); } private static void testWithTryCatch(Test t) { t.reset(); long l = System.currentTimeMillis(); for (int j = 0; j < 10; j++) for (int i = 1; i <= 100000000; i++) try { t.method1(i); } catch (Exception ignored) { } l = System.currentTimeMillis() - l; System.out.println("with try/catch method1 took " + l + " ms, result was " + t.getValue()); } }
打印
with try/catch method1 took 9723 ms, result was 2 without try/catch method1 took 9456 ms, result was 2 with try/catch method1 took 9672 ms, result was 2 without try/catch method1 took 9476 ms, result was 2 with try/catch method1 took 8375 ms, result was 2 without try/catch method1 took 8233 ms, result was 2 with try/catch method1 took 8337 ms, result was 2 without try/catch method1 took 8227 ms, result was 2 with try/catch method1 took 8163 ms, result was 2 without try/catch method1 took 8565 ms, result was 2
从这些结果中,似乎使用try / catch略慢,但并不总是这样。
在Windows 7,Xeon E5450上运行,使用Java 7更新7。