一個月前心血來潮瞎折騰了下Nodejs,用ab和JMeter進行簡單地壓力測試后,不得不佩服它的速度與性能(備注:測試比較了幾個框架后得出的結果)。Nodejs是什么,一個基於chrome的javascript V8引擎的platform,特點是事件驅動,異步非阻塞IO模型,輕量。本文不是給Nodejs做廣告的,它只是一個引子,關於Nodejs的具體信息大家自己google吧,這里就不多作說明了。之所以是個引子,正由於它是基於V8引擎的,而讓我感嘆V8的威力時,不由想到另外一個firefox的JS引擎SpiderMonkey,進而忍不住想PK一下他們的性能。
說明下PK用的環境吧,
1. 環境一:i5處理器,win7,vs2008
2. 環境二:酷睿2代(呵呵,5年前的老機器了),linux(ubuntu),codeblocks
Win7+VS2008下軟件測試環境安裝與配置:
1. 安裝Nodejs(V8)
這個比較簡單,直接到nodejs.org下載直接安裝就OK了,方便起見可以把安裝后的node.exe路徑添加到環境變量PATH里。
2. 安裝SpiderMonkey
- 下載SpiderMonkey1.8.0(Ver1.8.5在win7編譯有點問題,暫未解決,所以用了1.8.0)
- 下載並安裝MozillaBuild
- 可選:如果后面安裝時顯示找不到WINNT6.1.mk,就把SpiderMonkey的src/config文件夾下的WINNT6.0.mk改名為WINNT6.1.mk
- 啟動VS環境Command Prompt,執行MozillaBuild的start-msvc9.bat
- 進入SpiderMonkey源碼目錄運行make –f makefile.ref BUILD_OPT=1
- 編譯完成后在WINNT6.1_OPT.OBJ文件夾下會生成js.exe(方便起見,添加;路徑到PATH環境變量)
OK,windows環境搞定。
備注:本來是想通過V8和SpiderMonkey原生C/C++庫來運行js代碼進行測試的,那樣結果應該更客觀,V8環境調試運行都成功了,但是SpiderMonkey編譯后,運行測試代碼時顯示加載dll失敗了,在使用和運行SpiderMonkey編譯后的js.exe時倒是沒有問題,也沒太多時間研究,就放棄了。最后決定通過Nodejs(V8)的node.exe和SpiderMonkey的js.exe來進行測試。
Ubuntu下軟件測試環境安裝與配置:
1. 安裝Nodejs(V8)
- 安裝編譯依賴源sudo apt-get install g++ curl libssl-dev apache2-utils
- 安裝git(安裝過的可省略) sudo apt-get install git-core
- 通過git取源代碼git clone git://github.com/ry/node.git
- 編譯
- cd node
- ./configure
- make
- sudo make install
- 運行node -v,出版本的話就OK
2. 安裝SpiderMonkey
- 下載deb包(spidermonkey-bin_1.8.1.4-2ubuntu5_i386.deb, libmozjs0d_1.8.1.4-2ubuntu5_i386.deb)
https://launchpad.net/ubuntu/hardy/i386/spidermonkey-bin/1.8.1.4-2ubuntu5
- 先安裝libmozjs,再安裝spidermonkey-bin
- 運行js -v,出版本就OK
OK,ubuntu環境搞定。(這里做個廣告,ubuntu真的不錯,很方便,后續准備寫篇關於ubuntu的博文,介紹下windows到ubuntu切換后ubuntu下可替用的軟件,有興趣的給我留言,呵呵)
關於測試方式,我簡單寫了三個待測試的js函數,分別是測試多循環計算的,測試字典dict存取的,測試對象訪問的,具體test.js代碼如下:
- // 測試多循環計算
- computerFunc = function() {
- var result = 0;
- for (var i = 0; i < 1000; i++) {
- for (var j = 0; j < 1000; j++) {
- result += i;
- }
- }
- return result;
- };
- // 測試字典dict存取
- dictFunc = function() {
- var dict = {};
- var key = "key";
- var result = 0;
- for (var i = 0; i < 1000000; i++) {
- dict[key + i] = i;
- }
- for (var item in dict) {
- result += dict[item];
- }
- return result;
- };
- // 測試對象訪問
- objFunc = function() {
- var result = 0;
- var OBJ = function(c) {
- this.count = c;
- };
- OBJ.prototype.get_count = function() {
- return this.count;
- }
- for (var i = 0; i < 1000000; i++) {
- var o = new OBJ(i);
- result += o.get_count();
- }
- return result;
- };
- if (typeof(print) != "function")
- print = console.log;
- //以下三個函數,每次測試時只運行其中一個
- print(computerFunc());
- print(dictFunc());
- print(objFunc());
然后怎么看運行時間呢,我是在C代碼下分別通過nodejs的node.exe和SpiderMonkey的js.exe啟動運行js代碼,通過C的time庫來計算運行時間的。C的代碼如下:
- #include<stdio.h>
- #include<stdlib.h>
- #include<time.h>
- int main(int argc, char* argv[]) {
- clock_tstart, end;
- start= clock();
- //測試V8或Spidermonkey時切換以下兩行
- system("node.exetest.js");
- //system("js.exe test.js");
- end= clock();
- doubleoffset = (double)(end - start) / CLOCKS_PER_SEC;
- printf("%f,second\n", offset);
- return0;
- }
Ok,一切就緒,結果如何呢?
Windows下的運行結果
|
循環計算 |
Dict存取 |
對象訪問 |
Nodejs(V8) Ver0.6.13 |
0.129s |
1.289s |
0.145s |
Spidermonkey Ver1.8 |
0.224s |
1.755s |
0.792s |
Ubuntu下的運行結果
|
循環計算 |
Dict存取 |
對象訪問 |
|
Nodejs(V8) Ver0.6.13 |
0.1078s |
3.3123s |
0.1382s |
|
Spidermonkey Ver1.8 |
3.4167s |
7.0412s |
2.7921s |
結果很明了,V8勝出。
結論
1. 各個測試結果都顯示V8在性能上比當前版本的Spidermonkey要出色很多。
2. 在Linux及多核計算能力一般的CPU環境下,異步非阻塞IO的V8性能優勢非常大。
3. Dict字典操作上,優勢沒有其他兩項明顯,說明V8在字典操作上的優化還有待進一步提高。期待后續新版本V8在這一項上性能的進一步優化。