保罗·格雷厄姆在《黑客与画家》中写道,Java属于B&D(捆绑与束缚)类型的语言。为何束缚手脚?因为要让新手和明星程序员写出类似质量的代 码,尽可能的抹消人的才华对程序的影响。不同于C/C++,老手和新手写出的Java代码不会有上百倍的耗时差距。但同样也导致了Java的一个弱点—— 不容易优化。很多优化Java代码的程序员必须要对JVM(虚拟机)进行优化,实际上增大了很多任务难度。

通过Python和Java这两个语言的优缺点,返回来看Scala,就能瞬间明白Scala的定位了。

首先,Scala不把程序员当傻子。当马丁·奥德斯基宣布Scala 2.12(http://www.scala-lang.org/news/roadmap-next) 将要简化语法,推出Scala "Don
Giovanni"项目的时候,在视频中说的很清楚:“Scala现在是为聪明人创造的,以后也是为聪明人服务的。”所以不同于Python让程序员用一
种方法做所有事情,Scala提供一整套工具,让程序员自由选择,无论是mutable数据结构,immutable数据结构,并行(parallel)
数据结构。然后在这些选择中,Scala再针对他们进行算法层面的特殊优化。Scala相信程序员的聪明才智,让程序员自行选择合适的结构,以针对变化万
千的任务需求,这点是Scala做得极好的地方。

再者,有人会说immutable数据结构占用内存,或者速度很慢。这是真的,但这不是Scala的错,而是这些结构就是这样定义的。可以看看这个视频:https://www.parleys.com/tutorial/scala-collections-performance
这里讲的是Scala集合的运行速度,是一个来自Goldman
Sachs的程序员讲他们为Java写的集合库(GSCollection)速度和内存消耗,但同时比较了gs-collection(goldmansachs/gs-collections ·
GitHub
),Java,和Scala库的速度。最后Scala的可变集合mutable原生库完爆Java,和gs-collection基本持平。

Scala的第二个优势,相较于Java而言,则是相信程序员的优化能力。在Scala with Style讲话中(https://www.youtube.com/watch?v=kkTFx3-duc8),马丁·奥德斯基说:“很多程序员会告诉我,他们一般会重构他们的Scala代码两三次,甚至三四次。”这听起来似乎非常的没有效率,但Scala就是这样的语言,每一次重构,代码的性能或者是可读性都会有极高的提升。


前就有人提到过,Scala新手和老手写出来的代码完全会呈现两种不同的风格,甚至新人根本不能读懂有经验的Scala程序员所写的代码,有人于是戏称:
“太好了,这样的话我们部门的实习生就不能乱碰我写的代码啦!”但其实不仅风格不同,执行效率差距也一定是巨大的。Scala提供一整套工具,但是要明白
什么时候用拿一种工具,哪些算法能够随意调用,哪些算法不能,这一定要依靠经验、研究和学习以及对源代码的理解才能得知。最简单的例子,Scala的
foreach()方法是高度优化过了的(尤其针对Range结构和Vector结构),但是fold()就不一定了。或者当受到诱惑想用
zipWithIndex()的时候,一定要明白这是两次循环,最好改用Vector(...).indices.foreach()的方法,或者
用.view来推迟执行。

像这样的地方还有很多。所以在这个层面上来讲,简直和C++非常的相似。从另外一个层面来讲,不仅仅是要理解语
言层面的优化,Scala作为一个社区而言,是非常追求运行速度的。Ruby社区就完全不同了,Ruby曾经是推特的主要语言。推特的团队找到了Ruby
团队,说,你们能不能让Ruby运行的快一点,我们有这个这个和这个建议。Ruby直接把这些建议拒绝了,因为它们会增加语言复杂度,让Ruby不能继续
做一个“fun”(好玩)的语言。而Python直接就立志做一个“Simple”(简单)的语言了。于是推特只好将后台换做Scala和Java的结
合。有一位在推特工作的知乎友人在我的一个回答下留言说推特换用Scala后,TypeSafe(Scala的母公司)还送去了一个蛋糕。

为了追求速度,Scala社区是绝对不会管所谓的“简单”或者是“好玩”,怎样有效率就怎样弄。与其专注于JVM的改进,Scala社区大部分在编译器上下功夫,比如很著名的Miniboxing(Miniboxing),
这是一个编译器增进器。Miniboxing做的是什么呢?只做一件事:防止auto-boxing和auto-unboxing。所有的泛型,尤其是原
生类泛型(Primitive
Types),诸如Int、Double等等,在进行各种操作的时候会自动取出和装回它们所属的类中去——这个我解释的不太好,但是可以看这里(Java 自动装箱与拆箱(Autoboxing and
unboxing)
)。

Miniboxing这样的插件可以让所有的原生类泛型再也不用自动装拆箱,从而将Scala的运行速度提升1.5倍到22倍(http://scala-miniboxing.org/benchmarks.html)。当然这样的东西可不是白来的,这是马丁·奥德斯基的PhD博士学生做的一个研究项目,然后为OOPSLA写了一篇论文(http://dl.acm.org/citation.cfm?id=2509537),所以怪不得这玩意Scala可以有,但其他语言想要有都没有。


一个Scala的很大优势就是所谓的Macro——宏。宏本身作为元编程而言,其实和运行速度是没有什么太大关系的,反而,因为对反射(Reflect)
的利用,可能会影响到速度。但Scala社区对宏的理解显然和最初的设计理念有偏差。因为Scala本身是没有传统意义的循环的(for-loop),所
以很多时候循环必须利用while或者foreach。但是部分追求效率的Scala程序员们利用宏为Scala写了一个传统循环,叫做cfor,被收录
在Spire(non/spire ·
GitHub
)数学计算库中。cfor的写法如下:

import spire.syntax.cfor._

// print numbers 1 through 10
cfor(0)(_ <</span> 10, _ + 1) { i =>
println(i)
}

而这玩意运行效率如何呢?https://www.chrisstucchio.com/blog/2014/learning_spire_cfor.html
文章中做了一次测评,将cfor和zip写的一个算法作比较——在公布结果之前,我想说的是,zip并不是一个高度优化的方法,所以本身就慢很多,cfor用了26.1毫秒运行,zip方法用了7.4
秒运行,这几乎是284倍的速度差距。


过这两点,Scala的一个优势就很明显了——多样化。当需要写简单的代码,像Python一样当脚本语言使用时,Scala提供大量的原生方法和数据结
构,可以很轻松的写出比较复杂的操作。但当需要速度的时候,又可以通过重构来获取数十倍或者上百倍的速度提升。通过Miniboxing一类的编译器增强
器,Scala在某些操作的速度是必定超过Java的。

最新文章

  1. 遇上了artTemplate做的东西
  2. 【深入】java 单例模式(转)
  3. Headless MSBuild Support for SSDT (*.sqlproj) Projects
  4. ajax返回son数据
  5. nau8822 codec driver 录音时mic bias 无法自动打开问题
  6. C++实现链栈的基本操作
  7. matlab,xls转换为mat文件
  8. javascript函数之arguments
  9. 2017北京国庆刷题Day4 morning
  10. clear read-only status问题的解决
  11. ACache【轻量级的开源缓存框架】
  12. 在java中如何实现字符串的反转
  13. Python二级-----------程序冲刺3
  14. JAVA字符串
  15. odoo TransientModels must have log_access turned on
  16. 用递归方法计算斐波那契数列(Recursion Fibonacci Sequence Python)
  17. Springboot+websocket+定时器实现消息推送
  18. [Laravel] 14 - REST API: Laravel from scratch
  19. 1.虚拟机中安装ubuntu
  20. 团队项目7——团队冲刺beta版本目录

热门文章

  1. vuex状态管理demo
  2. org.hibernate.AnnotationException: mappedBy reference an unknown target entity property
  3. linux网络编程——域名转换 gethostbyname与gethostbyaddr
  4. spring 学习(二)
  5. 关于zookeeper和zkfc的一些测试
  6. CentOS服务器上部署 oracle10gr2
  7. [luoguP1433] 吃奶酪(DP || Dfs)
  8. hdu 3804树链剖分+离线操作
  9. poj—— 3037 Saving Beans
  10. Ubuntu 16.04安装汇编编译器NASM