O Groovy Gurus,
此代码段大约运行1秒
for (int i in (1..10000000)) {
j = i;
}
虽然这个花了将近9秒
for (int i = 1; i < 10000000; i++) {
j = i;
}
为什么会这样?
答案 0 :(得分:9)
确定。这是我对为什么的看法?
如果将两个脚本转换为字节码,您会注意到
ScriptBytecodeAdapter .compareLessThan - &gt; ScriptBytecodeAdapter。compareTo - &gt; DefaultTypeTransformation。的compareTo
typehandling包中有其他类专门为数学数据类型实现compareTo方法,不确定为什么它们没有被使用(如果它们没有被使用)
我怀疑这是第二个循环花费更长时间的原因。 如果我错了或遗失了某些内容,请再次纠正我......
答案 1 :(得分:2)
在测试中,确保在采取措施之前“加热”JVM,否则您最终可能会触发平台中的各种启动操作(类加载,JIT编译)。连续多次运行测试。此外,如果您在进行垃圾收集时进行了第二次测试,则可能会产生影响。尝试运行每次测试100次并在每次测试后打印出时间,看看它告诉你什么。
答案 2 :(得分:1)
如果你可以像Jim建议的那样从启动时消除潜在的工件,那么我就会猜测Groovy中的Java风格for循环与原始的Groovy风格for循环没有那么好实现。它只是在用户请求之后从v1.5开始添加,因此它的实现可能是一个事后的想法。
您是否看过为两个示例生成的字节码,看看是否有任何差异?有一个关于Groovy性能here的讨论,其中一条评论(来自一个'johnchase')说:
我想知道你看到的差异是否与Groovy如何使用数字(原语)有关 - 因为它将所有原语包装在它们等效的Java包装器类中(int - &gt; Integer),我想这样会使事情变慢位。我有兴趣看到使用包装类而不是整数来循环10,000,000的Java代码的性能。
那么也许最初的Groovy for循环不会受此影响?我真的只是在猜测。