Java如何使低效的代码运行得比高效的代码更快?

Tia*_*Zhu 9 java optimization performance jit jvm

在下面的代码片段中,Foo1是一个每次bar()调用方法时递增计数器的类.Foo2做同样的事情,但有一个额外的间接水平.

我希望Foo1速度比Foo2实际Foo2速度快40%Foo1.JVM如何优化代码,Foo2运行速度比Foo1

一些细节

  • 测试执行了java -server CompositionTest.
  • 运行测试java -client CompositionTest会产生预期的结果,Foo2慢于Foo1.
  • 切换循环的顺序没有区别.
  • 在sun和openjdk的JVM上使用java6验证了结果.

代码

public class CompositionTest {

    private static interface DoesBar {
        public void bar();
        public int count();
        public void count(int c);
    }

    private static final class Foo1 implements DoesBar {
        private int count = 0;
        public final void bar() { ++count; }
        public int count() { return count; }
        public void count(int c) { count = c; }
    }

    private static final class Foo2 implements DoesBar {
        private DoesBar bar;
        public Foo2(DoesBar bar) { this.bar = bar; }
        public final void bar() { bar.bar(); }
        public int count() { return bar.count(); }
        public void count(int c) { bar.count(c); }
    }

    public static void main(String[] args) {
        long time = 0;
        DoesBar bar = null;
        int reps = 100000000;

        for (int loop = 0; loop < 10; loop++) {
            bar = new Foo1();
            bar.count(0);

            int i = reps;
            time = System.nanoTime();
            while (i-- > 0) bar.bar();
            time = System.nanoTime() - time;

            if (reps != bar.count())
                throw new Error("reps != bar.count()");
        }
        System.out.println("Foo1 time: " + time);

        for (int loop = 0; loop < 10; loop++) {
            bar = new Foo2(new Foo1());
            bar.count(0);

            int i = reps;
            time = System.nanoTime();
            while (i-- > 0) bar.bar();
            time = System.nanoTime() - time;

            if (reps != bar.count())
                throw new Error("reps != bar.count()");
        }
        System.out.println("Foo2 time: " + time);
    }
}
Run Code Online (Sandbox Code Playgroud)

Bil*_*l K 1

尝试预测现代语言的性能并不是很有成效。

JVM 不断被修改以提高常见、可读结构的性能,相反,这会使不常见、笨拙的代码变慢。

只要尽可能清楚地编写您的代码 - 然后,如果您确实确定了您的代码实际上被认为太慢而无法通过书面规范的点,您可能需要手动调整某些区域 - 但这可能会涉及大量的,简单的想法,如对象缓存、调整 JVM 选项和消除真正愚蠢/错误的代码(错误的数据结构可能是巨大的,我曾经将 ArrayList 更改为 LinkedList,并将操作从 10 分钟减少到 5 秒,对 ping 操作进行多线程处理,发现 B 类网络的操作时间从 8 小时以上缩短到几分钟)。