【发布时间】:2009-05-28 12:33:51
【问题描述】:
O Groovy 大师,
这段代码 sn-p 运行大约 1 秒
for (int i in (1..10000000)) {
j = i;
}
而这个需要将近 9 秒
for (int i = 1; i < 10000000; i++) {
j = i;
}
为什么会这样?
【问题讨论】:
标签: groovy
O Groovy 大师,
这段代码 sn-p 运行大约 1 秒
for (int i in (1..10000000)) {
j = i;
}
而这个需要将近 9 秒
for (int i = 1; i < 10000000; i++) {
j = i;
}
为什么会这样?
【问题讨论】:
标签: groovy
好的。这是我对原因的看法?
如果您将两个脚本都转换为字节码,您会注意到
ScriptBytecodeAdapter.compareLessThan --> ScriptBytecodeAdapter.compareTo --> DefaultTypeTransformation.compareTo
typehandling 包中还有其他类专门为数学数据类型实现 compareTo 方法,不知道为什么不使用它们,(如果它们不被使用)
我怀疑这是第二个循环需要更长的时间的原因。 再次,如果我错了或遗漏了什么,请纠正我......
【讨论】:
在您的测试中,请务必在采取措施之前“预热”JVM,否则您可能最终会触发平台中的各种启动操作(类加载、JIT 编译)。也可以连续多次运行测试。此外,如果您在进行垃圾收集时进行了第二次测试,那可能会产生影响。尝试将每个测试运行 100 次,并在每次测试后打印出时间,看看会告诉你什么。
【讨论】:
如果您可以按照 Jim 的建议从启动时消除潜在的伪影,那么我会冒险猜测 Groovy 中的 Java 样式 for 循环的实现不如原始 Groovy 样式的 for 循环那么好。它只是在用户请求后从 v1.5 开始添加的,所以它的实现可能是事后才想到的。
您是否查看过为您的两个示例生成的字节码,看看是否有任何差异?有一个关于 Groovy 性能的讨论 here 其中一个 cmets(来自一个“johnchase”)是这样说的:
我想知道您看到的差异是否与 Groovy 如何使用数字(基元)有关 - 因为它将所有基元包装在其等效的 Java 包装类(int -> Integer)中,我想这会减慢一些速度.我有兴趣了解使用包装类而不是整数循环 10,000,000 次的 Java 代码的性能。
所以也许原始的 Groovy for 循环不会受到这种影响?不过,这只是我的猜测。
【讨论】: