文档章节

Yammer从Scala转向Java

山海经
 山海经
发布于 2013/08/25 12:18
字数 1687
阅读 234
收藏 1

近日,由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循环。这可以通过如下代码进行测试:

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

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

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

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

与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的开发者将大有裨益。

本文转载自:http://www.infoq.com/cn/news/2012/02/yammer-scala

山海经
粉丝 36
博文 159
码字总数 40723
作品 0
广州
程序员
私信 提问
Yammer 从 Scala 转向 Java

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

二胡
2012/02/01
3.5K
27
Java 8会干掉Scala吗?

2014-04-15 孙镜涛 InfoQ 最令人期待的Java 8已于2014年3月18日发布,该版本包含很多令人兴奋的新特性,被认为是自Java 5发布以来对Java做出的最大改变。对于开发者而言,最值得注意的特性包...

Yamazaki
2014/04/23
0
0
scala入门之windows下安装scala

因为scala是JVM上的语言,所以我们首先要安装Java运行环境。从oracle官网下载:jdk-7u21-windows-x32.exe(目前最新版本),然后安装。注意,scala只需要java的运行环境,也就是只需要安装:...

柳哥
2014/06/05
0
1
Dropwizard 0.9.2 发布,RESTful 网络服务

Dropwizard 0.9.2 发布,更新如下: Support@UnitOfWorkannotation outside of Jersey resources #1361 更多内容请看:release-notes Dropwizard是一个Java框架,用于开发易于运维,高性能的...

淡漠悠然
2016/01/21
1K
3
Java 8 vs Scala — Part II Streams API

这是本文的第 2 部分。第 1 部分在这里。 Stream 与 Collection 的比较 这是我按自己的意思给的一个十分简要的说明:collection 是一个有限的数据集,而 stream 是数据的一个序列,可以是有限...

oschina
2015/11/18
4K
16

没有更多内容

加载失败,请刷新页面

加载更多

JDBC中The server time zone value '???ú±ê×??±??' is ............. 的错误

在JDBC使用的时候有时候会出现java.sql.SQLException: The server time zone value '???ú±ê×??±??' is unrecognized or represents........的错误. 原因:出现这个的原因是因为 mysql返......

一对二
6分钟前
0
0
HBase基本命令与新版本Java API

简介 有关HBase的安装可以参考hbase安装 我们可以通过hbase shell和hbase数据库进行交互,也可以通过Java-api和hbase数据库交互,这里我们使用的是hbase-client。 主要是介绍2.0重大重构之后...

trayvon
8分钟前
1
0
Quartz原理解析

Quartz原理解析 最近项目中好多地方都需要用到定时器,一开始用的是netty的hashWheel,后来发现删除任务的时候不是很好删除,于是就放弃了,然后选择了Quartz。 hashWheel定时器和Quartz的区...

石日天
今天
2
0
explain详解

EXPLAIN列的解释 table 显示这一行的数据是关于哪张表的 type 这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为 const(读常量,最多只会有一条记录匹配,由于是常量,实际上...

周慕云
今天
1
0
Oracle 修改或新增数据后查不到数据

修改或新增数据后数据库中SQL能查到但执行程序却查不到 因为AutoCommit is OFF 所以 每次新增或修改数据后都要commit 一下,不然只是post edit 的话,执行程序能查到的只是未更新的数据。...

南风末
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部