假设我们有一个给定的接口(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
?答案是否取决于两个建议中的哪一个 我们使用的实现还是无关紧要?
答案是否取决于估计的通话次数?对于什么数量的计数,使用one 或first 方法更好?
最佳答案
可能使用带有检查的那个会有轻微的性能优势。我非常怀疑它在任何现实生活中的应用中是否重要。
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/