写点什么

Yammer 从 Scala 转向 Java

  • 2012-02-01
  • 本文字数:2600 字

    阅读完需:约 9 分钟

近日,由 Yammer 雇员 Coda Hale 发给 Typesafe 的 Scala 商业管理层的邮件通过 YCombinator 被泄漏出来并在 GitHub 上刊出。该邮件确认 Yammer 正在将其基础设施栈从 Scala 迁回至 Java,原因在于 Scala 的复杂性与性能问题。

Yammer 的公关 Shelley Risk 向 InfoQ 证实该邮件只代表 Coda Hale 的个人意见而非 Yammer 的官方声明;随后,Coda Hale 又在 http://codahale.com/the-rest-of-the-story/ 上发表了一篇文章。在该文章中,Coda 澄清说这个消息是来自于 Donald Fischer( Typesafe 的 CEO)对早前一个 tweet 的回复。

更新:近日,Yammer 已经发布了声明,宣布对该问题的立场,声明证实了上述猜测。声明还指出任何语言都会有瑕疵(不仅仅是 Scala),该邮件只不过是尝试提出一些建议以改进 Scala 的性能与其他问题。最后,声明说到在构建任何高性能项目时(Scala 是其产品环境)都有一些问题需要解决;该邮件旨在帮助 Scala 不断改进。

虽然 Coda 并未打算公开该邮件,但他通过 Gist(后来被删除了)将其放到了 GitHub 上以获得其他朋友的反馈;然而,邮件内容后来被共享出来并得到了大范围传播。

回到 2010 年 8 月,Coda 在 Yammer Engineering 博客上说他们将要转向 Scala 。其目标是继续运行在 JVM(出于性能原因)上,这个转变的结果就是减少了约 50% 的代码:

Artie 最初的原型采用 Java 编写,但在一个周末的试验中,我尝试使用 Scala 2.8 重新实现一次。一天后,代码行数减少了约一半,并添加了几个特性。我震惊了,Java 开发者很容易找,但 Scala 团队却能完成更多工作

一年过后,这个决定发生了变化

目前在 Yammer,我们正在将基础设施迁回至 Java,同时以遗留库的形式继续对 Scala 提供支持。这个过程并不是那么急,我们刚刚开始,但需要很长时间。本质在于使用 Scala 而非 Java 作为我们的默认语言所产生的摩擦和复杂性并未被足够的生产力提升或是维护工作的减少而抵消。我们或许还会在产品中使用 Scala,但主要的开发将会使用 Java。

Stephen Colebourne(近日发表了文章 Is Scala the new EJB2?)对这封邮件做了点评,其要点总结如下:

  • 作为一门语言,Scala 中有很多颇具见地的想法。但它是门非常复杂的语言。
  • 除了 Scala 所引入的概念与具体实现外,要想编写地道的 Scala 还有一个文化的问题,有时突然就蹦出来一个最佳实践:完全不管不顾社区。
  • 我当然知道学习(以及教授)Scala 的困难程度与重要性。因为我们不可能在没人学习 Scala 的情况下找到人,这个事实非常重要。
  • 构建工具链导致开发很不舒服。这主要是因为 SBT 导致了 Maven 与 Ant 的边缘化——而他们是 Java 生态圈中的两个主要的构建工具。
  • 每个主要的 Scala 发布都不兼容于之前的版本,这导致 Scala 开发者总是在开发新的库并重新发明轮子。
  • 借助于分析与检查字节码,我们可以通过采用一些简单的规则实现 100 倍的改进:
    • 不要使用 for 循环
    • 不要使用 scala.collection.mutable
    • 不要使用 scala.collection.immutable
    • 总是使用 private[this]
    • 不要使用闭包
  • 我和开发团队讨论了这个问题(迁回至 Java),并且演示了两个代码基,结果是大家普遍同意进行切换。毫无疑问,我们肯定对 Scala 的某些方面还不太熟悉,但这不足以让我们还固守在 Scala 上。

其中一些问题可能不太重要(比如说,一门语言越流行,那么雇佣的开发者的经验就会越多),其中一些是根据经验来测试的。比如说,其中一条建议就是不要使用 for 循环。这可以通过如下代码进行测试:

复制代码
<pre>
scala>
var start = System.currentTimeMillis();
var total = 0;for(i <- 0 until 100000) { total += i };
var end = System.currentTimeMillis();
println(end-start);
println(total);
114
scala>
scala<
var start = System.currentTimeMillis();
var total = 0;var i=0;while(i < 100000) { i=i+1;total += i };
var end = System.currentTimeMillis();
println(end-start);
println(total);
8
</pre>

这里使用 for 循环(与"until"模式,很多 Scala 程序员都习惯这么用)要比对应的 while 循环慢很多,虽然使用 while 循环的可读性差一些。同样循环的 Java 实现对于 for 和 while 来说都是 2ms。

我们做的另一个测试是通过从一个包含 Integer 对象的数据集合中加载来看看可变 map 的性能(这可以在 Java 与 Scala 中进行对比,装箱的损耗应该差不多)。

复制代码
<pre>
scala>
val m = new scala.collection.mutable.HashMap[Int,Int];
var i = 0;
var start = System.currentTimeMillis();
while(i<100000) { i=i+1;m.put(i,i);};
var end = System.currentTimeMillis();
println(end-start);
println(m.size)
101
scala>
val m = new java.util.HashMap[Int,Int];
var i = 0;
var start = System.currentTimeMillis();
while(i<100000) { i=i+1;m.put(i,i);};
var end = System.currentTimeMillis();
println(end-start);
println(m.size)
28
scala>
val m = new java.util.concurrent.ConcurrentHashMap[Int,Int];
var i = 0;
var start = System.currentTimeMillis();
while(i<100000) { i=i+1;m.put(i,i);};
var end = System.currentTimeMillis();
println(end-start);
println(m.size)
55
</pre>

与 java.util.HashMap 相比,性能是相同的,与 java.util.concurrent.ConcurrentHashMap 相比,Java 的速度要比 Scala 快一倍。Java 集合类超越了 Scala(以上测试基于 OSX JVM 1.6.0_29 与 Scala 2.9.1,在文本撰写之际的最新版本)。

但遗憾的是,在 Scala 库 API 中有很多 Scala 集合,他们需要通过代码中的隐式转换从 Java 对象类型转换为 Scala 对象类型。出于性能原因,这需要大量的重写。

如果 Scala 编译器通过 invokedynamic 生成代码,那么闭包(lambdas)的性能还会得到改进,这是后续版本的 Scala 将会做的事情。此外,在 JDK 8 中(将会给 Java 带来 native lambdas 与 method handles)将会有很多的性能改进,这些改进都可以为 Scala 所用。

最后,Scala 在解决版本之间的不兼容问题上面临着越来越多的压力(不仅仅是2.9.2 与2.9.3 之间的小改进)。Typesafe 并未发布Scala 未来路线图的官方声明,也没有说明何时才会有稳定的二进制版本能够实现不同版本之间代码的兼容。如果能够实现向后兼容,那么就会有更多稳定的库出现,并且会形成一个社区仓库,这对未来有志于使用Scala 的开发者将大有裨益。

查看英文原文: Yammer Moving from Scala to Java

2012-02-01 04:285992
用户头像

发布了 88 篇内容, 共 271.0 次阅读, 收获喜欢 9 次。

关注

评论

发布
暂无评论
发现更多内容

帮师姐把100个Excel中符合条件的数据,汇总到1个Excel里

程序员晚枫

Python Excel 自动化办公

为什么大家都喜欢“人天”作为估算单位?

Bruce Talk

Scrum 敏捷开发 Agile

压缩解压工具:Keka中文版

真大的脸盆

Mac Mac 软件 压缩工具 解压缩软件 解压软件

架构蓝图--软件架构的“4+1”视图模型

涛哥 数字产品和业务架构

软件架构 模型

解决 Font '宋体' is not available to the JVM

源字节1号

微信小程序 开源 软件开发

【Redis源码分析】Server启动过程

零点999

redis Redis 协议 Redis 核心技术与实战 Redis 数据结构 redis 底层原理

明道云在制造行业的五个实施案例与建议

明道云

Elasticsearch简介以及索引原理

数新网络官方账号

Flink CDC

数新网络官方账号

面试高频问题之C++编译过程

小万哥

c++ 程序员 后端 编译 开发

Kotlin 学习笔记(二)—— 数据类、密闭类、循环写法以及常用集合操作符

修之竹

android kotlin

矢量绘图UI设计:Sketch 95.3中文激活版

真大的脸盆

Mac UI Mac 软件 ui设计

浅谈Spark分布式计算

数新网络官方账号

Web3社交网络的另一种思路 - Oi! Network解析

股市老人

CDC工具之Debezium

数新网络官方账号

代码覆盖率最佳实践

数新网络官方账号

浅谈数据仓库工具——Hive

数新网络官方账号

QQ截图图片不够清晰解决方法

源字节1号

微信小程序 开源 软件开发

机器学习算法(五):基于企鹅数据集的决策树分类预测

汀丶人工智能

数据挖掘 机器学习 决策树

CDC工具之Canal

数新网络官方账号

Kubernetes 简介及其调度原理

数新网络官方账号

赠票 | 在北京,见证边缘的力量

俞凡

前缀和算法练习集

timerring

前缀和

零代码零距离,明道云开放日北京站圆满结束

明道云

如何选择合适的智慧公厕设备厂家?

光明源智慧厕所

智慧城市

mybatis xml文件热加载实现

越长大越悲伤

mybatis springboot java

华为云ECS/HECS:中小企业上云第一步

IT科技苏辞

关于GPT-4的产品化狂想

脑极体

AI

Handler消息传递机制浅析

芯动大师

Activity Handler runOnUiThread

往往排查很久的问题,最后发现都非常简单。。。

艾小仙

Java kafka spring

pdf编辑工具:PDF Expert 中文激活版

真大的脸盆

Mac PDF Mac 软件 PDF编辑 pdf编辑工具

Yammer从Scala转向Java_Java_Alex Blewitt_InfoQ精选文章