我有一个微基准测试,显示出非常奇怪的结果:
@BenchmarkMode(Mode.Throughput)
@Fork(1)
@State(Scope.Thread)
@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1000)
@Measurement(iterations = 40, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1000)
public class Chaining {
private String a1 = "111111111111111111111111";
private String a2 = "222222222222222222222222";
private String a3 = "333333333333333333333333";
@Benchmark
public String typicalChaining() {
return new StringBuilder().append(a1).append(a2).append(a3).toString();
}
@Benchmark
public String noChaining() {
StringBuilder sb = new StringBuilder();
sb.append(a1);
sb.append(a2);
sb.append(a3);
return sb.toString();
}
}
我期望两个测试的结果相同或至少非常接近。但是,差异几乎是5倍:
# Run complete. Total time: 00:01:41
Benchmark Mode Cnt Score Error Units
Chaining.noChaining thrpt 40 8538.236 ± 209.924 ops/s
Chaining.typicalChaining thrpt 40 36729.523 ± 988.936 ops/s
有人知道这怎么可能吗?
字符串连接a + b + c
是Java程序中非常常见的模式,因此HotSpot
JVM对其进行了特殊的优化:-XX:+OptimizeStringConcat
默认情况下为ON。
HotSpot JVM可以识别new StringBuilder().append()...append().toString()
字节码中的模式,并将其转换为优化的机器代码,而无需调用实际的Java方法,也无需分配中间对象。即,这是复合JVM固有的一种。
这是此优化的源代码。
另一方面,sb.append(); sb.append(); ...
没有特别处理。就像常规的Java方法调用一样,编译此序列。
如果您使用来重新运行基准测试-XX:-OptimizeStringConcat
,则两个变体的性能将相同。
问题内容: 考虑以下示例: 我不确定Java语言规范中是否有一项规定要加载变量的先前值以便与右侧()进行比较,该变量应按照方括号内的顺序进行计算。 为什么第一个表达式求值,而第二个表达式求值?我本来希望先被评估,然后再与自身()比较并返回。 这个问题与Java表达式中子表达式的求值顺序不同,因为这里绝对不是“子表达式”。需要 加载 它以进行比较,而不是对其进行“评估”。这个问题是特定于Java的,
这个问题与Java表达式中子表达式的求值顺序不同,因为在这里肯定不是“子表达式”。需要加载它进行比较,而不是“求值”。这个问题是特定于Java的,表达式来自一个真实的项目,而不是通常为棘手的面试问题而设计的牵强附会的不切实际的构造。它应该是比较和替换习语的一行替换 它比x86 CMPXCHG指令还要简单,因此在Java中应该使用更短的表达式。
基于此,我认为我应该完全开始在中使用
以下Python3.x整数乘法的平均运算时间在1.66s到1.77s之间: 如果将替换为,则需要在和之间。怎么会呢? 另一方面,在Java中则相反:在Java中更快。Java测试链接:为什么在Java中2*(i*i)比2*i*i快? 我运行每个版本的程序10次,以下是结果。
为什么比快?我使用的是CPython 3.5.2。 我试着改变我提升的幂,看看它是怎么做的,例如,如果我提升x的10或16的幂,它会从30跳到35,但如果我提升10.0作为浮动,它只是在24.1~4左右移动。 我想这和浮点转换和2次方有关,但我真的不知道。
问题内容: Python文档明确指出了调用。但是似乎在许多情况下,情况恰恰相反。它何时何地发生的原因在哪里记录,如何确定我的对象或方法将被调用。 编辑:只是为了澄清,我知道在优选中调用,但是我不清楚为什么优先于调用,而后者是文档状态将发生的原因。 编辑:从马克·迪金森的答案和评论中,它看起来像是: 丰富的比较替代 是它自己的,以它的(以及类似的,等等) 如果左对象是内置类或新样式类,而右对象是其子