java - 额外的 'if checks' 如果该值已经设置 - 什么更快,什么使用更多资源?

标签 java jvm micro-optimization premature-optimization microbenchmark

假设我们有一个给定的接口(interface):

public interface StateKeeper {

    public abstract void negateWithoutCheck();

    public abstract void negateWithCheck();

}

和以下实现:

class StateKeeperForPrimitives implements StateKeeper {
    private boolean b = true;

    public void negateWithCheck() {
        if (b == true) {
            this.b = false;
        }
    }

    public void negateWithoutCheck() {
        this.b = false;
    }
}

class StateKeeperForObjects implements StateKeeper {
    private Boolean b = true;

    @Override
    public void negateWithCheck() {
        if (b == true) {
            this.b = false;
        }
    }

    @Override
    public void negateWithoutCheck() {
        this.b = false;
    }
}

此外,假设方法negate*Check() 可以被调用1+ 次,很难说调用次数的上限是多少。

  • 问题是两种实现中哪种方法“更好” 根据执行速度、垃圾收集、内存分配等 - negateWithCheck 还是 negateWithoutCheck

  • 答案是否取决于两个建议中的哪一个 我们使用的实现还是无关紧要?

  • 答案是否取决于估计的通话次数?对于什么数量的计数,使用onefirst 方法更好?

最佳答案

可能使用带有检查的那个会有轻微的性能优势。我非常怀疑它在任何现实生活中的应用中是否重要。

premature optimization is the root of all evil (Donald Knuth)


您可以衡量两者之间的差异。让我强调一下,众所周知,这类事情很难可靠地衡量。

这里有一个简单的方法来做到这一点。如果检查识别出不必更改该值,则可以希望获得性能优势,从而节省了昂贵的内存写入。所以我相应地更改了您的代码。

interface StateKeeper {

    public abstract void negateWithoutCheck();

    public abstract void negateWithCheck();

}

class StateKeeperForPrimitives implements StateKeeper {

    private boolean b = true;

    public void negateWithCheck() {
        if (b == false) {
            this.b = true;
        }
    }

    public void negateWithoutCheck() {
        this.b = true;
    }
}

class StateKeeperForObjects implements StateKeeper {

    private Boolean b = true;

    public void negateWithCheck() {
        if (b == false) {
            this.b = true;
        }
    }

    public void negateWithoutCheck() {
        this.b = true;
    }
}

public class Main {

    public static void main(String args[]) {

        StateKeeper[] array = new StateKeeper[10_000_000];

        for (int i=0; i<array.length; ++i)
            //array[i] = new StateKeeperForObjects();
            array[i] = new StateKeeperForPrimitives(); 

        long start = System.nanoTime();

        for (StateKeeper e : array)
            e.negateWithCheck();
            //e.negateWithoutCheck();

        long end = System.nanoTime();

        System.err.println("Time in milliseconds: "+((end-start)/1000000));
    }
}

我得到以下信息:

           check  no check
primitive   17ms    24ms
Object      21ms    24ms

当检查总是多余的时,我没有发现检查有任何性能损失,反过来因为值总是必须更改。

两件事:(1) 这些时间安排不可靠。 (2) 该基准与任何现实生活中的应用相去甚远;我必须制作一个包含 1000 万个元素的数组才能真正看到一些东西。

我会简单地选择没有检查的函数。我非常怀疑在任何实际应用程序中,您是否会从具有检查的函数中获得任何可衡量的性能优势,但该检查容易出错并且是更难阅读。

关于java - 额外的 'if checks' 如果该值已经设置 - 什么更快,什么使用更多资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19182405/

相关文章:

java - 64 位升级后关闭 Tomcat JVM 服务的时间更长

java - "Error: JAVA_HOME is not defined correctly."在构建 Jikes rvm

vectorization - 是否可以说服 clang 在不使用内在函数的情况下自动矢量化此代码?

c - 搜索短排序的 double 组

java - imageio.read 与 mac

Java DataOutputStream 只工作一次

java - 在另一个类的方法中使用驱动程序类中的变量 (java)

elasticsearch - 为什么 Elasticsearch Cluster JVM 内存压力不断增加?

java - ITextPdf : Printing Arabic strings from Right To Left (RTL)

assembly - 如何强制 NASM 将 [1 + rax*2] 编码为 disp32 + index*2 而不是 disp8 + base + index?