近日,由Yammer雇员Coda Hale发给Typesafe的Scala商业管理层的邮件经过YCombinator被泄漏出来并在GitHub上刊出。该邮件确认Yammer正在将其基础设施栈从Scala迁回至Java,缘由在于Scala的复杂性与性能问题。 html
Yammer的公关Shelley Risk向InfoQ证明该邮件只表明Coda Hale的我的意见而非Yammer的官方声明;随后,Coda Hale又在http://codahale.com/the-rest-of-the-story/上发表了一篇文章。在该文章中,Coda澄清说这个消息是来自于Donald Fischer(Typesafe的CEO)对早前一个tweet的回复。 java
更新:近日,Yammer已经发布了声明,宣布对该问题的立场,声明证明了上述猜想。声明还指出任何语言都会有瑕疵(不只仅是Scala),该邮件只不过是尝试提出一些建议以改进Scala的性能与其余问题。最后,声明说到在构建任何高性能项目时(Scala是其产品环境)都有一些问题须要解决;该邮件旨在帮助Scala不断改进。 git
虽然Coda并未打算公开该邮件,但他经过Gist(后来被删除了)将其放到了GitHub上以得到其余朋友的反馈;然而,邮件内容后来被共享出来并获得了大范围传播。 程序员
回到2010年8月,Coda在Yammer Engineering博客上说他们将要转向Scala。其目标是继续运行在JVM(出于性能缘由)上,这个转变的结果就是减小了约50%的代码: github
Artie最初的原型采用Java编写,但在一个周末的试验中,我尝试使用Scala 2.8从新实现一次。一天后,代码行数减小了约一半,并添加了几个特性。我震惊了,Java开发者很容易找,但Scala团队却能完成更多工做
一年事后,这个决定发生了变化: 闭包
目前在Yammer,咱们正在将基础设施迁回至Java,同时以遗留库的形式继续对Scala提供支持。这个过程并非那么急,咱们刚刚开始,但须要很长时间。本质在于使用Scala而非Java做为咱们的默认语言所产生的摩擦和复杂性并未被足够的生产力提高或是维护工做的减小而抵消。咱们或许还会在产品中使用Scala,但主要的开发将会使用Java。
Stephen Colebourne(近日发表了文章Is Scala the new EJB2?)对这封邮件作了点评,其要点总结以下: 工具
其中一些问题可能不过重要(好比说,一门语言越流行,那么雇佣的开发者的经验就会越多),其中一些是根据经验来测试的。好比说,其中一条建议就是不要使用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的开发者将大有裨益。