golang与node.js的http模块性能对比测试

358 views
Skip to first unread message

lulu Lee

unread,
Aug 12, 2012, 5:53:39 AM8/12/12
to golang-china
重新对go1和nodejs的http模块性能进行了测试,go的http模块的性能已经有了比较大的提升,hello world的测试甚至比nodejs还有稍稍好一点 

如果测试哪里可能有问题的,欢迎指正。 

--
@QLeelulu | FaWave, Net4 Team | qlee...@gmail.com | 学海无涯,回头是岸 

marschant

unread,
Aug 12, 2012, 6:03:59 AM8/12/12
to golang...@googlegroups.com
学习,哇哈哈~ 我觉得只看helloworld不怎么能说明问题哇

--
官网: http://golang-china.org/
IRC: irc.freenode.net #golang-china
@golangchina

minux

unread,
Aug 12, 2012, 6:43:44 AM8/12/12
to golang...@googlegroups.com

2012/8/12 lulu Lee <qlee...@gmail.com>

重新对go1和nodejs的http模块性能进行了测试,go的http模块的性能已经有了比较大的提升,hello world的测试甚至比nodejs还有稍稍好一点 

如果测试哪里可能有问题的,欢迎指正。 
用Go 1.0.2测试吧(Node.js用最新的0.8.6,那Go也用最新版吧)
Go产生的数据量还是比Node.js多得多,可以试试把Date header给去掉。
(bradfitz抱怨过好几次time.Format慢,有几次想在net/http里面重新实现一个专用的time.Format,
所以值得去掉Date header看看结果;如果有兴趣可以测试下Go的开发版,default分支,因为
rsc已经把time.Format的性能提升成成2.7x了,CL 6278047;不光如此,default分支还有一
些工具链的优化,可能会有些影响)
(更公平的是改Go的测试程序让两者的输出一样)
有条件的话,试试gccgo编译的结果(这个稍微有点麻烦,如果发行版没提供gcc 4.7.1(这个对应于
Go 1.0.1)的话,得自己编译gccgo);看看编译器对性能的影响;(优化选项注意要和node.js的
优化选项尽可能一致;当然,如果自己编译gccgo的话,node.js也应该从源代码安装了)

还有呀,最好是把ab/webbench放到另外一台机器上,免得互相影响。

最后,我还是认为这个benchmark没太大意义。

lulu Lee

unread,
Aug 12, 2012, 8:49:12 AM8/12/12
to golang...@googlegroups.com
minux:
mac book 上装的是go 1.0.2的,但是OS X下的ab测试工具有bug,ubuntu上直接就apt-get安装了(懒得配GOROOT,PATH什么的 =。=),我也不知道go1是不是最新的1.0.2版本。
主要是测试默认的http模块,所以没想做太多的修改。
ab/webbench在同一台机器上确实是不妥,机器倒是有两台,不过网络环境是无线的,测试更加不靠谱,所以都在一条机器上测试了。
你提到的几点非常有参考意义,后面有时间再细测一下。

对于hello world的测试有没意义,我觉得是非常有意义,这在一定程度上反应了语言在性能方面可以达到的高度。因为http模块包括了网络io处理,请求解析等都可以直接体现语言处理在性能方面的能力。
很多人喜欢说要测具体逻辑代码才有意义,连数据库读写什么的(我觉得这个才没意义,数据库驱动模块实现的优劣直接影响测试结果)

--
官网: http://golang-china.org/
IRC: irc.freenode.net #golang-china
@golangchina

marschant

unread,
Aug 12, 2012, 9:51:09 AM8/12/12
to golang...@googlegroups.com
这样子哇
查看版本 go ersion

lihui

unread,
Aug 12, 2012, 12:24:30 PM8/12/12
to golang...@googlegroups.com
支持。

1)要测试就测试惯用法,而不是在生产实践中几乎没有人使用的优化方法。因为我们总是测试一当下的实现性能,而非理论性能。
2)hello world的测试是很有意义的,比实际应用更有意义。不完整的地方在于,可能就是这个helloworld只涵盖了小数据的响应,而没有测试大数据的响应,比如2M大小的响应。

实际上这个测试足够说明了go在复杂业务环境下的优势的优势了。因为hello world是nodejs的最佳应用场景。

不能因为是go的fans,就不顾一切的为之辩护,而丧失客观行。


2012/8/12 lulu Lee <qlee...@gmail.com>

minux

unread,
Aug 12, 2012, 1:21:47 PM8/12/12
to golang...@googlegroups.com

2012/8/12 lulu Lee <qlee...@gmail.com>

mac book 上装的是go 1.0.2的,但是OS X下的ab测试工具有bug,ubuntu上直接就apt-get安装了(懒得配GOROOT,PATH什么的 =。=),我也不知道go1是不是最新的1.0.2版本。
go version的输出是go1,那就是Go 1.0版本。 
主要是测试默认的http模块,所以没想做太多的修改。
那至少得改改Header,你看Go的响应多那么多东西呢。 
ab/webbench在同一台机器上确实是不妥,机器倒是有两台,不过网络环境是无线的,测试更加不靠谱,所以都在一条机器上测试了。
不能用网线直连么? 
对于hello world的测试有没意义,我觉得是非常有意义,这在一定程度上反应了语言在性能方面可以达到的高度。因为http模块包括了网络io处理,请求解析等都可以直接体现语言处理在性能方面的能力。
很多人喜欢说要测具体逻辑代码才有意义,连数据库读写什么的(我觉得这个才没意义,数据库驱动模块实现的优劣直接影响测试结果)
问题是没有任何业务代码的Node.js基本上就是纯C++代码。而真正用Node.js的时候会这样么?
不会。

先撇开benchmark本身有没有意义的问题不说;假设它有意义,那么这个评测说明了什么?Go比Node.js快?
任何benchmark只能说明你所测试问题的性能,但是我相信你要用Go或者是Node.js绝对不是去跑hello world的。
我觉得这个benchmark充其量说明Go标准库的net/http和C++实现http_parser比(Node.js里面这部分用Javascript
实现的代码可以忽略不计了),性能不相上下。可是实际应用中,一旦加入了任何业务代码,结果可能就完全
不同了。

shiwei xu

unread,
Aug 12, 2012, 1:41:25 PM8/12/12
to golang...@googlegroups.com
非常同意 minux 的看法。我之前也表达过类似的观点,没有业务代码的 hello world,其实是拿 go 和 c++ 比,不具太大的参考价值。这有点类似之前有评测说 c++ 的 sort 没有 python 的 sort 慢。其实本质上是拿 c++ 的 sort 和 c 写的 sort 算法比,并且用的是不同的 sort 算法。

--
官网: http://golang-china.org/
IRC: irc.freenode.net #golang-china
@golangchina

shiwei xu

unread,
Aug 12, 2012, 1:42:20 PM8/12/12
to golang...@googlegroups.com
typo: 这有点类似之前有评测说 c++ 的 sort 比 python 的 sort 慢。

lihui

unread,
Aug 12, 2012, 9:33:49 PM8/12/12
to golang...@googlegroups.com
不要一提到性能测试,就感觉是批评go不行。楼主未必是要证明在实际使用中nodejs比go http强,更不是要说v8比gc强,javascript比go强,而是在当前情况下,nodejs http与go http 性能相近。由此我们自然可以推断出在实际应用中的性能预期(即go更强)。

做科学实验,就是要隔离不相关的条件,以取得各组成的特性,测试集要是完整的,并且测试集元素要是相互独立的,单纯的。这样的结果才能够增进我们对整个系统的理解,可以通过它来建立针对任何应用的心理预期。而不是用一个现实中复杂到无法分析实例来进行测试,对于这样的结果,我们除了嗨一声外,别无所获。



2012/8/13 shiwei xu <xushi...@gmail.com>

KevinPan

unread,
Aug 12, 2012, 10:25:02 PM8/12/12
to golang...@googlegroups.com
不用“hello world”,用什么呢?“hello world”可以比较出语言层面的性能。大系统的性能基本和语言就无关了,完全是架构的占大头。

laputa

unread,
Aug 12, 2012, 10:33:43 PM8/12/12
to golang...@googlegroups.com
用“hello world”比较的是Go和C++的差异,而不是Go和Node.js,Node.js上业务总不会再用C++写,这样的比较只能说明一半的问题。

lulu Lee

unread,
Aug 12, 2012, 11:07:47 PM8/12/12
to golang...@googlegroups.com
首先,我做这个测试的主要目的不是要和nodejs比谁快谁慢,只是想要说明go的http模块在性能上已经有不俗的表现,大可以放心使用go来开发高性能的web应用。
其次,nodejs的http模块除了http_parser是C写的以为,其他的都是js写的( https://github.com/joyent/node/blob/master/lib/http.js#L28 )。而得益于google V8的强大,nodejs本身也不算慢( http://cnodejs.org/topic/4f16442ccae1f4aa2700104b ),不要说这完全是go和C的性能差异。

对于 @lihui 提到的大数据请求的测试,我也觉得是一个比较有必要的测试。

laputa

unread,
Aug 12, 2012, 11:44:36 PM8/12/12
to golang...@googlegroups.com
我了解node的http模块里,有部分是js写的,不知道比重多少。
如果像你说的那样,大部分是js写的,那我觉得大体可以说明问题。

minux

unread,
Aug 14, 2012, 12:24:05 AM8/14/12
to golang...@googlegroups.com
我把回复都写在一起了。

2012/8/13 lihui <ustc....@gmail.com>

1)要测试就测试惯用法,而不是在生产实践中几乎没有人使用的优化方法。因为我们总是测试一当下的实现性能,而非理论性能。
想测试理论性能也测不出来呀。
另:鉴于Node.js也输出Date header,所以去掉这个benchmark就不公平了;但是如果想测量
time.Format的overhead的的话可以试试这样,很简单,只要w.Header()["Date"] = nil就可以了。
但是Go Header里面多的Content-Type是必须得改,同时加上Connection: keep-alive
2)hello world的测试是很有意义的,比实际应用更有意义。不完整的地方在于,可能就是这个helloworld只涵盖了小数据的响应,而没有测试大数据的响应,比如2M大小的响应。
web测试可不仅仅是大小数据量这么简单;没有测试到的东西多了去了。比如最高支持的并发数,
比如响应的lattency,要求更高可能还有jitter。
还有,这个benchmark的代码覆盖率有多少?我觉得net/http可以砍掉90%以上的代码然后依然
可以支持这个benchmark,请问这样的话,这个benchmark说明了什么实际情况?
实际上这个测试足够说明了go在复杂业务环境下的优势的优势了。
这个测试绝对不可能说明Go在复杂业务环境下的优势。这么外推性能数据是极端危险的。
(换句话说,如果这样就能评测Go在复杂业务环境下的优势的话,明天Go Team就修改编译器,
检测这段代码,然后针对它生成更优化的代码,稍微优化一点这个性能可以高得多,因为这个
至少可以优化成收到请求就直接发固定的一段响应过去,可以根本不理GET的URL,以及送过来
的Header等等)
另:为了某个benchmark改编译器的事情还真发生过。
因为hello world是nodejs的最佳应用场景。
这么定位Node.js,Ryan要被气死了。 

不能因为是go的fans,就不顾一切的为之辩护,而丧失客观行。
我觉得数据量都不一致,很难得出任何有意义的结论。你要benchmark总要保证尽可能多的条件
是一致的,这样才有意义。另外,对于结果我没啥评论,我觉得更重要的是这个benchmark没意
义,具体是谁强谁弱得在benchmark有意义的情况下才有必要说。

2012/8/13 KevinPan <bit....@gmail.com>

不用“hello world”,用什么呢?“hello world”可以比较出语言层面的性能。大系统的性能基本和语言就无关了,完全是架构的占大头。
还是那句话,如果我把net/http裁剪到只支持这样trivial的应用,那么你还觉得这个benchmark有意义么? 
另外,你提到比较语言层面的性能,那用net/http就更不对了,因为这里还牵扯到io。
以及,Node.js的这个benchmark里面Javascript实现的部分有多少比例?

2012/8/13 lulu Lee <qlee...@gmail.com>
首先,我做这个测试的主要目的不是要和nodejs比谁快谁慢,只是想要说明go的http模块在性能上已经有不俗的表现,大可以放心使用go来
你只测试了这么一个trivial的程序,然后把结论推广到整个net/http模块;这合适么? 
我前面提过多次了,如果我裁剪net/http模块中没执行到的代码来提高性能,那么合适么?
开发高性能的web应用。
其次,nodejs的http模块除了http_parser是C写的以为,其他的都是js写的( https://github.com/joyent/node/blob/master/lib/http.js#L28 
http_parser是C++的;这是占大头的。Javascript写的是那些callback
另:谁要是觉得http协议的parser很简单的话,回去重读RFC。
)。而得益于google V8的强大,nodejs本身也不算慢( http://cnodejs.org/topic/4f16442ccae1f4aa2700104b ),不要说这完全是go和C的性能差异。
是不完全;但是绝对部分是C++写的(绝大部分指的是性能攸关的部分;80-20的定律不会不知道吧); 
你要比较V8和gc的性能,大可以用不需要io的benchmark。至少benchmark的绝大部分运行时间得
分别在执行Javascript和Go代码才有意义。

2012/8/13 laputa <ye.l...@gmail.com>

我了解node的http模块里,有部分是js写的,不知道比重多少。
如果像你说的那样,大部分是js写的,那我觉得大体可以说明问题。
我认为大部分这个很模糊的概念;是行数还是执行时间比例?从行数上说没任何意义,
因为可能大部分代码都根本没执行到;要是说实际执行的行数那倒是还稍微客观点;
我觉得更好的是执行时间占从时间的比例(而且这个还是跟benchmark的目的有关,
到底是比较V8和gc;还是比较http server?比较http server的话,首先你的测试覆盖
率得足够);

laputa

unread,
Aug 14, 2012, 1:32:05 AM8/14/12
to golang...@googlegroups.com
我说的比重,是指执行时间的比例。
因为没有仔细去分析代码,不好再做评论(PS,之前以为 js 部分就像一般的库,只是对 c++ 部分做简单封装)。


在 2012年8月14日 下午12:24,minux <minu...@gmail.com>写道:

我认为大部分这个很模糊的概念;是行数还是执行时间比例?从行数上说没任何意义,
因为可能大部分代码都根本没执行到;要是说实际执行的行数那倒是还稍微客观点;
我觉得更好的是执行时间占从时间的比例(而且这个还是跟benchmark的目的有关,
到底是比较V8和gc;还是比较http server?比较http server的话,首先你的测试覆盖
率得足够);

KevinPan

unread,
Aug 14, 2012, 1:46:38 AM8/14/12
to golang...@googlegroups.com
lulu Lee就是说go性能已经有大幅提升了,你一个一个抠字眼争论有什么意义?

我用go 1.0.2写了一个ip查询server,350万条ip数据,ab压力一下server qps轻松过万,比C的代码少了4/5,性能还是非常好,很满意。

node.js呢,性能也不差,但js语言的设计离go还是有一定距离,个人觉得没go好使,还是更喜欢go一些。

lulu Lee

unread,
Aug 14, 2012, 7:28:14 AM8/14/12
to golang...@googlegroups.com
在 2012年8月14日 下午1:46,KevinPan <bit....@gmail.com>写道:
lulu Lee就是说go性能已经有大幅提升了,你一个一个抠字眼争论有什么意义?

我用go 1.0.2写了一个ip查询server,350万条ip数据,ab压力一下server qps轻松过万,比C的代码少了4/5,性能还是非常好,很满意。

node.js呢,性能也不差,但js语言的设计离go还是有一定距离,个人觉得没go好使,还是更喜欢go一些。

go很好,不过推广和社区建设还需要更多的努力。

争论是非常有意义的,看怎么个争法。 @minux 提到的都是有理有据的,也是很独到的见解来的。我觉得这争论是非常有意义的。

@minux:
回到这个benchmark到底有没意义的问题上,有意义是肯定有意义的,但是有多大的意义呢? 这个得看你从多大的高度去看待这个benchmark和你期望的参考指标了。

至于测试覆盖率问题,这个测试确实是很片面,cookie、form解析、文件上传等等都没有覆盖到。
但是这个测试起码说明了在一个请求到达http里面的handler这部分的性能还是很高的,所以在用go开发web应用的时候,这一部分已经不会是你的性能瓶颈并可以有不俗的表现,至于你在handler里面的业务逻辑甚至是html模板的解析这些都应该不属于http模块的问题。
我本身想测试的是go的http模块的性能,而不是go语言本身(当然,这也依赖go语言本身的性能)。

这测试并无意比较nodejs和go本身的性能问题,之所以选择nodejs作为对比,是因为nodejs在这方面也有不俗的表现,选择nodejs作为对比在一定程度上更有说服力。

你提到的web方面还包括并发、延迟等等方面,这没错,不过这应该属于net包的范畴了。但是http包在测试中不俗的表现,也同时说明了net包在一定程度上的高效和go在io处理方面也有不错的表现。

好吧,这只是一个简单的测试,无论有没意义都好,应该都可以作为一个可以参考的结果。
Reply all
Reply to author
Forward
0 new messages