我在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内存。Java版本为1.7.0_45,Scala版本为2.10.2。
有关更多信息,请参见我的博客。
for
循环在Scala中不存在的原因,因为它们在Scala中具有某些特殊性?这两种方法看起来非常相似。另外,如果您将scala.collection.mutable.HashSet替换为java.util.HashSet会发生什么? - Diciutil.HashSet
和mutable.HashSet
的add
方法进行了快速微基准测试。添加一个字符串或100个不同的字符串,两者的性能大致相同。因此,我认为这不是Scala可变HashSet的问题。顺便说一下,我基于此示例进行了基准测试,使用Caliper避免了JVM上微基准测试的常见陷阱。 - Cyäegha