为什么添加try块可以加快程序速度?

16 浏览
0 Comments

为什么添加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日
0
0 Comments

我用 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 =============================

我认为它们基本上是一样的。

0
0 Comments

当一个方法中有多个长时间运行的循环时,其中一个循环可以触发整个方法的优化,对第二个循环产生无法预测的结果。避免这种情况的一种方法是:

  • 为每个循环提供自己的方法
  • 多次运行测试以检查结果是否可重复
  • 运行测试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。

0