Joh*_*ith 158 java memory performance scala
我很想研究Scala,并且有一个基本问题我似乎无法找到答案:一般来说,Scala和Java之间的内存性能和使用是否存在差异?
Rex*_*err 254
Scala使得很容易在没有意识到的情况下使用大量内存.这通常非常强大,但偶尔会很烦人.例如,假设您有一个字符串数组(称为array),以及从这些字符串到文件(称为mapping)的映射.假设您想要获取地图中的所有文件,并且来自长度大于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);
}
Run Code Online (Sandbox Code Playgroud)
呼!努力工作.在Scala中,执行相同操作的最紧凑方式是:
val bigEnough = array.filter(_.length > 2).flatMap(mapping.get)
Run Code Online (Sandbox Code Playgroud)
简单!但是,除非你非常熟悉集合的工作方式,否则你可能没有意识到这样做是为了创建一个额外的中间数组(带filter),并为数组的每个元素创建一个额外的对象(带有mapping.get,返回)一个选项).它还创建了两个函数对象(一个用于过滤器,一个用于flatMap),尽管由于函数对象很小,这很少是一个主要问题.
所以基本上,内存使用在原始级别是相同的.但是Scala的库有许多强大的方法,可以让你很容易地创建大量(通常是短命的)对象.垃圾收集器通常对这种垃圾非常好,但是如果你完全忘记了正在使用的内存,你可能会在Scala中遇到麻烦而不是Java.
请注意,计算机语言基准测试游戏Scala代码是以类似Java的方式编写的,以便获得类似Java的性能,因此具有类似Java的内存使用.您可以在Scala中执行此操作:如果您编写的代码看起来像高性能Java代码,那么它将是高性能的Scala代码.(您可以用更惯用的Scala风格编写它,但仍然可以获得良好的性能,但这取决于具体细节.)
我应该补充说,每花费一定的编程时间,我的Scala代码通常比我的Java代码更快,因为在Scala中我可以用更少的工作量完成繁琐的非性能关键部分,并且更多的注意力来优化算法和性能关键部分的代码.
Not*_*ing 100
我是新用户,所以我无法在上面给Rex Kerr的答案添加评论(允许新用户"回答"而不是"评论"是一个非常奇怪的规则btw).
我注册时只是为了回应"phew,Java是如此冗长和如此艰苦的工作"暗示Rex上面流行的答案.虽然您当然可以编写更简洁的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));
}
}
Run Code Online (Sandbox Code Playgroud)
当然,如果我们假装Eclipse没有为你做大部分的实际打字,并且每个保存的字符真的让你成为一个更好的程序员,那么你可以编写代码:
List b=new ArrayList();
for(String s:array)
if(s.length()>2 && mapping.get(s) != null) b.add(mapping.get(s));
Run Code Online (Sandbox Code Playgroud)
现在,我不仅救我花了输入完整的变量名和大括号(释放我花5秒钟思考深算法的思想)的时间,但我还可以在混淆比赛进入我的代码,并可能赚取外快假期.
Kev*_*ght 65
像Java一样编写Scala,你可以期望发出几乎相同的字节码 - 几乎相同的指标.
使用不可变对象和更高阶函数更"惯用"地写它,它会稍微慢一些.这个经验法则的一个例外是当使用类型params使用@specialised注释的通用对象时,这将创建甚至更大的字节码,通过避免装箱/取消装箱可以超过Java的性能.
另外值得一提的是,在编写可以并行运行的代码时,更多内存/更低速度是不可避免的权衡.惯用Scala代码在本质上远比典型的Java代码更具说明性,并且通常只有4个字符(.par)远离完全并行.
因此,如果
那么你会说Scala代码现在相对慢了25%,还是快了3倍?
正确的答案取决于你如何定义"性能":)
Pet*_*ego 31
计算机语言基准游戏:
速度测试 java/scala 1.71/2.25
内存测试 java/scala 66.55/80.81
因此,这个基准测试表明java的速度提高了24%,scala的内存增加了21%.
总而言之,这并不重要,在真实世界的应用程序中无关紧要,因为大部分时间都是由数据库和网络消耗的.
一句话:如果Scala让你和你的团队(以及你离开时让项目结束的人)更有成效,那么你应该去做.
Set*_*eth 20
其他人已经就紧密循环回答了这个问题,尽管Rex Kerr的例子之间似乎有明显的性能差异,我已经评论过了.
这个答案的确针对那些可能会将紧密循环优化作为设计缺陷进行调查的人.
我对Scala相对较新(大约一年左右),但到目前为止,它的感觉是它允许你相对容易地推迟设计,实现和执行的许多方面(有足够的背景阅读和实验:)
延期设计特点:
延期实施功能:
延期执行功能:(抱歉,没有链接)
对我来说,这些功能可以帮助我们走上快速,紧凑的应用之路.
Rex Kerr的例子在延迟执行的哪些方面有所不同.在Java示例中,延迟分配内存,直到计算出Scala示例延迟映射查找的大小.对我来说,它们似乎是完全不同的算法.
以下是我认为更像是苹果与苹果等效的Java示例:
val bigEnough = array.collect({
case k: String if k.length > 2 && mapping.contains(k) => mapping(k)
})
Run Code Online (Sandbox Code Playgroud)
没有中间集合,没有Option实例等.这也保留了集合类型,所以bigEnough类型是Array[File]- Array的collect实现可能会像Kerr先生的Java代码那样做.
上面列出的延迟设计功能还允许Scala的集合API开发人员在将来的版本中实现快速的特定于Array的集合实现,而不会破坏API.这就是我所指的踩着速度之路.
也:
val bigEnough = array.withFilter(_.length > 2).flatMap(mapping.get)
Run Code Online (Sandbox Code Playgroud)
withFilter我在这里使用的方法不是filter修复中间收集问题,但仍然存在Option实例问题.
Scala中简单执行速度的一个例子是日志记录.
在Java中,我们可能会写:
if (logger.isDebugEnabled())
logger.debug("trace");
Run Code Online (Sandbox Code Playgroud)
在Scala中,这只是:
logger.debug("trace")
Run Code Online (Sandbox Code Playgroud)
因为在Scala中调试的消息参数具有类型" => String",我认为它是一个无参数函数,在评估它时会执行,但文档会调用pass-by-name.
编辑{Scala中的函数是对象,因此这里有一个额外的对象.对于我的工作,一个简单对象的重量值得消除日志消息被不必要地评估的可能性.}
这不会使代码更快,但它确实使它更快更快,而且我们不太可能拥有经历和整体清理其他人的代码的经验.
对我而言,这是Scala中的一致主题.
硬代码无法捕获为什么Scala更快,尽管它有点暗示.
我觉得这是Scala中代码重用和代码质量上限的结合.
在Java中,令人敬畏的代码经常被迫成为一个难以理解的混乱,因此在生产质量API中并不可行,因为大多数程序员都无法使用它.
我非常希望Scala可以允许我们中的爱因斯坦实现更有能力的API,可能通过DSL表达.Scala中的核心API已经走在了这条道路上.
olu*_*ies 11
@higherkinded关于这个主题的演示文稿 - Scala Performance Considerations,它进行了一些Java/Scala比较.
工具:
伟大的博文:
rye*_*guy 10
Java和Scala都编译成JVM字节码,所以区别并不大.您可以获得的最佳比较可能是计算机语言基准测试游戏,它基本上表示Java和Scala都具有相同的内存使用率.在列出的一些基准测试中,Scala仅略微慢于Java,但这可能只是因为程序的实现不同.
实际上,它们都非常接近,不值得担心.使用像Scala这样更具表现力的语言所获得的工作效率提升远远超过最小化(如果有的话)性能.
| 归档时间: |
|
| 查看次数: |
76461 次 |
| 最近记录: |