【发布时间】:2014-10-25 03:06:50
【问题描述】:
我在 Scala 和 Java 版本的实现之间遇到了一些几乎相同的性能差异。我看到 Java 版本比 Scala 版本快 68%。知道为什么会发生这种情况吗?
Java 版本:
public class Util {
public static Set < String > toBigramsJava(String s1) {
Set <String> nx = new HashSet <String> ();
for (int i = 0; i < s1.length() - 1; i++) {
char x1 = s1.charAt(i);
char x2 = s1.charAt(i + 1);
String tmp = "" + x1 + x2;
nx.add(tmp);
}
return nx;
}
}
Scala 版本:
object Util {
def toBigramsScala(str: String): scala.collection.mutable.Set[String] = {
val hash: scala.collection.mutable.Set[String] = scala.collection.mutable.HashSet[String]()
for (i <-0 to str.length - 2) {
val x1 = str.charAt(i)
val x2 = str.charAt(i + 1)
val tmp = "" + x1 + x2
hash.add(tmp)
}
return hash
}
}
测试结果:
scala> Util.time(for(i<-1 to 1000000) {Util.toBigramsScala("test test abc de")})
17:00:05.034 [info] Something took: 1985ms
Util.time(for(i<-1 to 1000000) {Util.toBigramsJava("test test abc de")})
17:01:51.597 [info] Something took: 623ms
系统:
我在 Ubuntu 14.04 上运行此程序,具有 4 个内核和 8Gig RAM。 Java 版本 1.7.0_45,Scala 版本 2.10.2。
我的blog 上有更多信息。
【问题讨论】:
-
虽然这不是一个问题...您可以将其修改为一组匹配的问题和答案。
-
我建议你看一下字节码,看看有什么区别。
-
这可能是对 Scala 中不存在的 Java
for循环的优化,因为它们在 Scala 中有一些特殊性?这两种方法看起来确实相同。另外,如果将 scala.collection.mutable.HashSet 替换为 java.util.HashSet 会发生什么? -
你可能对我刚刚找到的这篇文章感兴趣。看来for循环确实是问题所在:ochafik.com/blog/?p=806
-
对于它的价值,我只是对
util.HashSet和mutable.HashSet的add方法做了一个快速的微基准测试。添加一个字符串或 100 个不同的字符串,我对两者的性能大致相同。所以在东部,我不认为这是 Scala 的可变 HashSet 的错。仅供参考,我的基准测试基于this example,它使用 Caliper 来避免 JVM 上微基准测试的常见缺陷。
标签: java performance scala