Go vs erlang

来自开放百科 - 灰狐
跳转到: 导航, 搜索

GoErlang 语言方面的一些比较:

Erlang和Go的并行化concurrent比较

说到concurrent,一般会想到Erlang和Go语言,这两种语言的主打特性都是concurrent,Erlang有着20多年的历史,是为简化开发电信大并发和高可靠性应用而发明的语言,Go是Google从2007年开始设计,2009年opensource出来的,Go属于一种system language,opensource的就算这两种语言吧,公司内私有的语言则有TNSDL,SDL的一个变种,以前写过一篇SDL和Erlang比较的文章,这三种concurrent语言各有不同,下面看看:

目录

1、语言设计

Erlang的实现基于虚拟机beam,Go是编译型语言,有着独成一体的compiler(不同于gcc,Go很好的解决了依赖的问题,所以编译go程序时不需向编译c程序那样指定include和library),TNSDL和GO类似,属于native执行。Erlang和TNSDL主要是为电信级应用服务的,而Go的concurrent则更具有通用性,这点主要体现在concurrent的设计,Erlang和SDL是基于process之间传递message,而Go是goroutine组成,再加上channel,Go通过把process和message解耦使得Go的设计更有通用性和灵活性,应用可以根据自己的需求决定是否需要channel的处理。routine加channel的设计在stackless python也有(有些人说Go = C + stackless Python),正是channel的灵活性使Go中不需要Erlang中的PID,Go中的go无返回值,Erlang中的spawn则返回PID。

Erlang没有对message buf进行控制,使用Go的channel则可控制channel的capacity,make(chan int, 100)

2、Library支持

Erlang有着20多年的历史,OTP中各种behavior,driver支持使得使用Erlang得心应手。Go的历史短得多,library仍有欠缺。

3、scheduler调度器

从实现的角度看Erlang中每个process都有自己的heap,所以无法共享内存,总体来说Erlang的scheduler与Linux kernel非常相似;Go和SDL属于native执行,这里主要讨论公平性的问题,Erlang中每个process有reduction,类似于Linux kernel中process的time slice,Go是native执行,那么Go的runtime是如何控制每个goroutine的公平性呢?答案是没有,native执行的goroutine无法像Erlang那样保证公平性,goroutine只能在syscall、io、channel read write操作时才能有机会重新执行schedule函数,以执行其余的goroutine。在concurrent语言中,如不能很好的解决公平调度和优先级调度是个很大的问题。

鉴于Go现在还不是太成熟,或许以后会有改进,scheduler和GC都有很多的讨论,现在scheduler的实现逻辑及其简单(G & M),与Erlang 调度器相比更是简单(里面有些bug,还有公平性的问题)。

  • Erlang scheduler位于:otp/erts/emulator/beam/erl_process.c
  • Go scheduler位于:go/src/pkg/runtime/proc.c

4、memory model 内存模型

Erlang中每个process有自己的heap,stack在heap的底部,这里的stack是Erlang process的stack,类似于Java中的操作数栈,stack向下增长,stack top如遇到heap top,则进行GC,GC后stack移到新的地方。

Go是native执行,goroutine的stack是segment stack,TNSDL的runtime也是使用这种segment stack,segment stack就是一个程序中有很多stack执行,stack的切换则通过setjmp,longjmp实现的。(setjmp和longjmp的一个主要应用就是concurrent,另一个是在C中模拟try catch)

5、GC垃圾回收

Erlang的GC属于分代算法,有个old heap,有minor gc和full sweep,总体来说和Java类似,只不过Erlang没有mark的过程,直接根据rootset找到所有Eterm放在新分配的heap的。

Go现在是mark-sweep,以后会使用IBM的低延时GC算法。

6、高可靠性

Erlang中有个builtin的高可靠性,如link和monitor机制。

Go是一个通用性的设计,虽没有built-in的link和monitor,goroutine则可使用defer来实现link的效果。

7、性能

Go的实际目标之一就是高性能,这也是为什么go是一种编译型语言。理论上分析goroutine的性能会好于Erlang的process,但软件设计原则中性能只是衡量标准之一而不是全部。

好了,话太多,就说到这里了,个人还是很喜欢Go的设计,未来程序语言的实际应该像go和Erlang那样扔掉mulitthreading的设计(Java,Python),同时channel的使用使得go的实际更具通用性和灵活性,这是concurrent语言被行业接受非常关键性的因素。

链接

分享您的观点
个人工具
名字空间

变换
操作
导航
工具箱