scala vs java,性能和内存? [关闭]

问题

我很想研究Scala,并且有一个基本问题我似乎无法找到答案:一般来说,Scala和Java之间的内存性能和使用是否存在差异?


#1 热门回答(240 赞)

Scala使得很容易在没有意识到的情况下使用大量内存。这通常非常强大,但偶尔会很烦人。例如,假设你有一个字符串数组(称为array),以及从这些字符串到文件的映射(称为mapping)。假设你想要获取 Map 中的所有文件,并且来自长度大于2的字符串。在Java中,你可能会

int n = 0;
for (String s: array) {
  if (s.length > 2 && mapping.containsKey(s)) n++;
}
String[] bigEnough = new String[n];
n = 0;
for (String s: array) {
  if (s.length <= 2) continue;
  bigEnough[n++] = map.get(s);
}

呼!努力工作。在Scala中,执行相同操作的最紧凑方式是:

val bigEnough = array.filter(_.length > 2).flatMap(mapping.get)

简单!但是,除非你非常熟悉集合的工作方式,否则你可能没有意识到这样做是为了创建一个额外的中间数组(withfilter),以及数组的额外对象forevery元素(带有mapping.get,返回一个选项)。它还创建了两个函数对象(一个用于过滤器,一个用于flatMap),但由于函数对象很小,因此很少成为主要问题。

所以基本上,内存使用在原始级别是相同的。但Scala的库有许多强大的方法,可以让你很容易地创建大量(通常是短暂的)对象。垃圾收集器通常对这种垃圾很好,但是如果你完全忘记了正在使用的内存,你可能会在Scala中遇到麻烦而不是Java。

请注意,计算机语言基准测试游戏Scala代码是以类似Java的方式编写的,以便获得类似Java的性能,因此具有类似Java的内存使用。你可以在Scala中执行此操作:如果你编写的代码看起来像高性能Java代码,那么它将是高性能的Scala代码。 (Youmaybe能够以更惯用的Scala风格编写它,并且仍然可以获得良好的性能,但这取决于具体细节。)

我应该补充说,在编程时花费的时间,我的Scala代码通常比我的Java代码更快,因为在Scala中我可以用更少的努力完成繁琐的非性能关键部分,并且更多的注意力来优化算法和代码性能关键部分。


#2 热门回答(95 赞)

我是新用户,所以我无法在上面给Rex Kerr的答案添加评论(允许新用户"回答"而不是"评论"是一个非常奇怪的规则btw)。

我注册只是为了回应"笨蛋,Java是如此冗长和如此艰苦的工作"暗示雷克斯上面流行的答案。虽然你当然可以编写更简洁的Scala代码,但给出的Java示例显然很臃肿。大多数Java开发人员会编写如下代码:

List<String> bigEnough = new ArrayList<String>();
for(String s : array) {
  if(s.length() > 2 && mapping.get(s) != null) {
    bigEnough.add(mapping.get(s));
  }
}

当然,如果我们假装Eclipse没有为你做大部分的实际打字,并且每个保存的角色真的让你成为一个更好的程序员,那么你可以编写代码:

List b=new ArrayList();
for(String s:array)
  if(s.length()>2 && mapping.get(s) != null) b.add(mapping.get(s));

现在,我不仅节省了输入完整变量名称和花括号的时间(让我花费5秒钟来思考深度算法思想),但我也可以在混淆竞赛中输入我的代码并可能获得额外的现金假期。


#3 热门回答(62 赞)

像Java一样编写Scala,你可以期望发出几乎相同的字节码 - 几乎相同的指标。

使用不可变对象和更高阶函数更"惯用"地写它,它会稍微慢一些。这个经验法则的一个例外是当使用类型参数使用266522255注释的通用对象时,这将创建甚至更大的字节码,通过避免装箱/拆箱可以超过Java的性能。

另外值得一提的是,在编写可以并行运行的代码时,更多内存/更低速度是不可避免的权衡。惯用Scala代码在本质上远比典型的Java代码更具声明性,并且通常仅仅是完全并行的4个字符(.par)。

因此,如果

  • Scala代码比单个线程中的Java代码长1.25倍
  • 它可以很容易地分成4个核心(现在甚至在笔记本电脑中也很常见)
  • 对于原始Java的并行运行时间(1.24 / 4 =)0.3125x

那么你会说Scala代码现在相对慢了25%,还是快了3倍?

正确的答案取决于你如何定义"性能":)