Golang 很出色,为何它比 Scala/JVM 更胜一筹?

我是在几个月前学习Golang的,这要感谢@normanmaurer和@MegOnWheels的提议!倒不是因为我想要抹黑Scala和JVM,而是由于它们在将近十年后开始显得很糟糕。

为什么JVM开始显得很糟糕?

我当初开始使用JVM时,对于应用程序及其虚拟机/运行时环境彼此分开来感到很高兴。在几乎专职编写了9年的Scala代码后,我对它逐渐厌恶起来。原因何在?

因为JVM方面的差异让我开发出易于预测(言外之意:稳定)的应用程序极其困难。一个版本这么做,下一个版本搞坏了它,所以从一位优秀程序员的角度来看,你不得不另想办法,避开运行时环境方面的问题和功能。

其次,为了使用最新的功能特性,比如TLS服务器名称指示(SNI)――TLS1.3问世之后,该特性其实不是最先进的,你就要确保JVM/运行时环境是最新版本,无论想在哪里使用该特性,就得如此(TLSSNI是Java7->8)。

如果你是根本不用肩负运行职责的程序员,这可能对你来说是可以接受的,但是我不得不关注自己编写的代码的运行,就跟我不得不关注代码本身那样!

那么什么让golang在我看来如此出色?

你得到了静态链接的二进制文件。没有运行时环境,根本不用安装任何东西。

从部署的角度来看这尤为出色,因为你只要操心你的二进制文件及其资产(要是有的话)。

另外值得一提的是,由于我的Scala/Java.jar包(捆绑了所有依赖项)很少小于60MB,加上不小于500MB的JVM,这样一来浪费了大量的磁盘空间,许多方面需要定期更新。我的golang二进制文件却总共很少超过13MB。

最后但并非最不重要的一点是,scala-sbt这个构建工具糟糕透顶。真是这样。在我看来,它是人类有史以来所想出的一款最糟糕的构建工具!经常破坏向后兼容性,需要我处理新插件,真是糟透了!

我想要一款专门构建代码,并生成一种有用的二进制文件格式的构建工具。

这是“可靠”的工具实际上要做的事情。除了超级丰富的功能(比如测试、模糊以及所有这种优秀特性)外,它还要可靠地构建代码,又不需要我精心维护配置文件!到目前为止,简单的Makefile文件足以满足我的所有要求。

另外,我之前在Scala/JVM上需要Disk-Space时,rm-rf ~/.ivy2基本上解决了这个问题,因为你从sbt获取的所有依赖项jar包都驻留在此。但是一旦你这么做,你可能会另谋职业,因为一些工件/jar包可能不复存在,因而破坏你构建的代码。与之相反,在Golang中,我只要使用gitclone命令把依赖项源代码克隆到我的代码库,将它作为子模块添加到git,或者直接使用git,添加依赖项代码即可。

Scala二进制不兼容性(对原始文章的后续更新)

许多人指出,拥有二进制依赖项缓存几乎就跟拥有源代码一样好。

有没有遇到过多个Scala版本的情况?或者在Scala这个领域待的时间太短,不知道Scala二进制不兼容性?如果你喜欢这种东西,它们确实很出色。但是我不喜欢。我不想查出某某软件包这样的所有依赖项:它们只能在Scala2.9上运行,但需要为你的2.10项目、2.11或其他版本的项目重新编译。

inline错误修复(同样在原始文章发表后补充上去)

我不知道你们是怎么一个情况,反正我喜欢修复我使用的别人代码中的错误。

看到别人得益于我的代码,这让我有满满的自豪感,也让我感到很高兴。

所以,只要我不得不查明Scala/JVM方面的问题,我通常采取的程序就是下载该库源代码。然后试图让那个开发人员所用的构建工具运行起来。有时候这个工具是sbt,有时候是ant,有时候是maven,有时候是我听都没听说过的某个工具。听起来很好吗?

现在,我要花时间让这个工具运行起来,然后才能花时间来实际修复代码。

浪费时间啊!

如果你已经有源代码,如果我已经为目前的版本对它们进行了编译,如果你只要找到某一行代码,改动它,然后测试代码,岂不是要容易得多?

还是说,你宁可经历那个维护人员的构建工具的整个构建过程,把因而获得的.jar包放到你的缓存中,或者部署它,然后可能再次下载它,不得不改动构建的代码以便使用这个新的工件?

从简单的逻辑角度来看,我总是会选择第一个,因为它让我避免了许多头痛的问题,让我得以专注于手头的问题。

交叉编译

诚然,JVM上的这个问题还没有到你为自己的平台搞一个切实可行的Java运行时环境(JRE)的地步。在我看来,让无比庞大的JVM在你的RaspberryPI上运行也许不是使用其CPU的最佳方法。

那么,go如何处理这个问题呢?罗布·派克(RobPike)有一场精彩的演讲,介绍了go编译器的内部原理,为我们作了清楚的解释。自go1.7以来,你再也没有必要使用C这种语言了,而是可以让golang径直由Go编译成ASM。太棒了!

所以,为了在OSX上为我的RaspberryPI交叉编译一些纯粹的go代码,我只要运行:

GOOS=freebsd GOARCH=arm GOARM=6 go build src/*.go
就是这样。用scp命令传输该二进制文件,结果令人满意。何不在ARM本身上面这么做呢?a)在我的英特尔i7八核处理器上所花的时间长得多,b)ARM上的golang最新只能适用于版本1.4,因为新版本会有一些问题,但是使用1.8-HEAD交叉编译完全很好。

性能

从我头几个月在生产环境下使用golang的情况来看,我可以证实,就本人的使用场合(主要是网络节点)而言,golang速度极快,尽管零拷贝机制(Zero-Copy)在FreeBSD上还未得到支持。

对我的应用程序而言,内存耗用只是原来JVM项目的大概十分之一,因而在我们的数据中心操作过程中降低了对内存的要求,因而之前使用的JVM内存中大约十分之六从我们的FreeBSD虚拟机中释放出来,因而为我们新的客户机/应用程序腾出了大量资源。

结束语

Golang会成为我新的主要语言,Scala只是偶尔用一下,用于需要之前由我开发的软件得到支持的现有客户机。

文章转载自 开源中国社区 [http://www.oschina.net]

时间: 2025-01-21 19:02:41

Golang 很出色,为何它比 Scala/JVM 更胜一筹?的相关文章

介绍四款性价比方面很出色的塔式服务器

与机架服务器相比,在价格方面塔式服务器会便宜些具有有很大优势,因此很多企业都很关注塔式服务器的动向,作主流的服务器产品,不仅仅只在处理器运用最新的双核技术,同时,在其它配件如内存.硬盘等等都应该采用最前沿的技术.今天笔者给大家介绍四款性价比方面很出色的塔式服务器,赶快和我一起关注一下吧! IBM System x3500 IBM System x3500是一款双路5U塔式服务器,标配1颗45纳米的Xeon E5405四核处理器,核心频率2.0GHz,前端总线1333MHz,四核共享12M二级缓存

带有镜头的数字照相机可以拍摄很出色的照片

带有镜头的数字照相机可以拍摄很出色的照片,但是要想把照相机植入到更小型设备中却是一件很困难的事情.因为镜头越小要想制作出精确的曲面就越困难.但Rambus的传感器研究科学家Patrick Gill想到了一种规避的办法,不用镜头,而是用螺旋形来采集和映射来自于各个方向的光线. 上面的这张图片的顶图就是用这种光栅采集到的图像.这张又小又模糊的图片人是很难辨认的,但经过传感器的处理器识别之后,目标图形变成了中图的样子.虽然它在清晰度上跟原型(底图)有较大差距,但是已不妨碍我们观察出它是什么图片了:达芬

屁股决定脑袋,董明珠和雷军的表现都很出色

摘要: 12月14日是一个热闹的日子,小米宣布12.66亿入股美的集团,参与美的的智能家居计划.同时,在中国企业家杂志的年会上,小米雷军和格力董明珠两大冤家再次聚首,而今年的聚首仍然 12月14日是一个热闹的日子,小米宣布12.66亿入股美的集团,参与美的的智能家居计划.同时,在中国企业家杂志的年会上,小米雷军和格力董明珠两大冤家再次聚首,而今年的聚首仍然是以董明珠对雷军放炮开场,而雷军上台后只是做了小米战略阐述,并未进行激烈反击. 在大多数人看来,董明珠已经在人气上因自己激烈言语败给了雷军,所

范帅惊喜阿联神勇:实在他防守和奔跑都很出色

<新泽西星报>消息,在前一场比赛输给森林狼之后,网队主教练范德维奇在赛后发布会上第一个提到的就是他的球队打出的努力程度. "今天,我们取得了进步,"范德维奇表示. 是的,他们迎来了两名重要的伤兵的回归,一个是易建联,一个是杜林.前者是被网队视为可以成为未来球队一大主要核心的年轻球员,后者则是一个有经验的拥有领导能力和比赛能量的老将.对森林狼的比赛,此两将都是替补上阵,结果都发挥出色. 易建联复出的首战相当完美,他的膝伤看起来都没题目了.今天的第二战,易建联也相当出色,得到1

好吧,就算没有什么很出色的,但可是我慢慢学过来的

书中的内容很硬啊. 慢慢理解了很多电商的编码及构架原因. 自我欣赏.

《JVM故障诊断指南》之3 —— Java 线程: JVM持有内存的分析

前面我们已经讨论过JVM里不同的堆空间,这节我们会给你提供教程,是关于如何从你的活动的应用Java线程中确定它持有多少堆空间,以及在哪里占用.这里有个来自Oracle Weblogic 10.0生产环境的真实案例,它能使你更好的理解分析过程. 我们也会演示这种情况,过多的垃圾收集或者堆空间内存占用问题并不总是由于真实的内存泄露引起,也可能是由于线程执行模型问题和太多的短生命对象引起. 后台 Java线程是JVM基础的一部分.你的Java堆空间内存占用不仅仅是由于静态的和长生命的对象导致,还有可能

2016企业开发趋势:Lightbend关于JVM开发者的调查

Lightbend最近调查了2100个JVM(包括Java和Scala)开发者,进行了以下研究: 开发趋势和IT基础设施趋势之间的相互关系. 各家公司在怎样用最新技术实现他们的应用程序. 新兴技术的实际生产使用率统计分析. 报告全文题为:"2016企业开发趋势:2100个JVM开发者的云.容器和微服务分析",分析了从使用重量级J2EE服务器到微服务和轻量级容器来构建应用程序,这个变革背后的主要驱动力. 如下图所示,参与调查的开发者来自于不同的公司: 调查主要得出了以下三个发现: 微服务

JVM 使用 Akka 执行异步操作详解教程

如何通过以下方式实现并发性:     并行地在多个数据集上执行相同的操作(就像 Java 8 流一样)    显式地将计算构建成异步执行某些操作,然后将结果组合在一起(就像 future 一样). 这两种方法都是实现并发性的不错方式,但是您必须将它们明确地设计到应用程序中. 在本文和接下来的几篇文章中,我将着重介绍一种不同的并发性实现方法,该方法基于一种特定的程序结构,与显式编码方法不同.这种程序结构就是 actor 模型.您将了解如何使用 actor 模型的 Akka 实现.(Akka 是一个

从 Node.js 到 Golang 的迁徙之路

本文讲的是从 Node.js 到 Golang 的迁徙之路, 由 Digg 的软件工程师 Alexandra Grant 所作,最初发表在 Medium. 我在大学时期就开始涉猎 JavaScript 并会随便写一些网页.我把 JS 当作写 C 语言和 Java 时候的一种小憩,并且我认为它是一种相当受限制的语言,它一直在鼓吹能够实现一些令用户叹为观止的特效和动画.我第一次教人编程就是用的 JS,因为它简单易学.能快速给开发者以可见的结果.将它与 HTML 和 CSS 代码写到一起,就能得到一个