考虑以下代码:
Foo result = array[index];
index = (index + 1) % array.length;
return result;为了执行一些最终操作,需要一个额外的变量。把它写成:
try {
return array[index];
} finally {
index = (index + 1) % array.length;
}还是会对业绩产生影响?一般来说,它被认为是一种好/坏的做法,如果是,为什么?
(在本例中,假定index是array的有效索引,代码不会抛出ArrayIndexOutOfBoundsException)
编辑:问题不在于是否需要使用try-finally,而在于通过选择使用它而获得的性能上的任何收益或损失。没有它,就会创建一个变量。使用它,返回的值存储在其他地方,也许以一种更有效的方式存储。
发布于 2018-07-02 15:52:07
如果没有finally,您实际上就声明了一个额外的Foo变量。
但它真的很贵吗?与这两种情况不同的是,内存中存在Foo对象。您刚刚添加了一个访问它的引用。
方法范围内对对象的引用确实很便宜。
你不应该担心这个。
此外,您不必使用finally语句来提高执行代码的性能。
代码的读者永远不会猜到这样的事情。
finally的作用是:
最终块总是在try块退出时执行。这确保即使发生意外异常也执行finally块。
和
将清理代码放入一个finally块始终是一个很好的实践,即使没有任何例外情况。
没有finally语句的第一段代码要清晰得多,没有任何间接读取。
因此,我建议坚持:
Foo result = array[index];
index = (index + 1) % array.length;
return result; 发布于 2018-07-02 16:07:35
如注释所述,主要开销是使用%而不是条件或掩码
您可以使用JMH运行基准测试。
static class Foo {
}
Foo[] array = new Foo[8];
int index = 0;
@Benchmark
public Foo simple() {
Foo result = array[index];
index = (index + 1) % array.length;
return result;
}
@Benchmark
public Foo withFinally() {
try {
return array[index];
} finally {
index = (index + 1) % array.length;
}
}
@Benchmark
public Foo withCondition() {
int i = index++;
if (index == array.length) index = 0;
return array[i];
}
@Benchmark
public Foo withMask() {
int i = index++;
return array[i & (array.length-1)];
}结果在我的机器上。你的里程会不一样
Benchmark Mode Cnt Score Error Units
ModMain.simple thrpt 25 132.473 ± 1.764 ops/us
ModMain.withCondition thrpt 25 363.077 ± 4.752 ops/us
ModMain.withFinally thrpt 25 130.179 ± 1.585 ops/us
ModMain.withMask thrpt 25 397.310 ± 3.506 ops/us越高越好。
简而言之,使用finally可能会稍微慢一些,但与其他选择相比,我不会担心它。
https://stackoverflow.com/questions/51139479
复制相似问题