Node介紹8-性能

程序完成以后城须,性能和穩(wěn)定性又是我們關(guān)注的焦點(diǎn)风瘦,本文總結(jié)一下工作中遇到的性能測(cè)試方法,當(dāng)然這里是針對(duì)node振峻。

性能分析是比較困難的工作臼疫,如果一個(gè)程序很慢,他可能把時(shí)間花在了CPU扣孟,I/O烫堤,網(wǎng)絡(luò)傳輸,垃圾回收和一些其他事情凤价。如果我們能找到變慢的地方鸽斟,并加以改進(jìn),那么我們的程序?qū)⒈雀?jìng)爭(zhēng)對(duì)手的優(yōu)秀料仗。

下面我們就看看有哪些方法可以幫助我們找到性能不佳的模塊湾盗。

日志

開(kāi)發(fā)app的程序員往往不喜歡使用日志,無(wú)論是iOS立轧,Android或者h(yuǎn)ybrid的開(kāi)發(fā)方案格粪,都有完善的調(diào)試機(jī)制,IDE更是好用的不行氛改,似乎日志只用在服務(wù)器端的程序帐萎,嵌入式和驅(qū)動(dòng)開(kāi)發(fā)中才用的到。不過(guò)這里想介紹一下日志也可以性能調(diào)試胜卤,所以給自己的模塊打上完整的日志疆导,是一種很好的開(kāi)發(fā)方法。

如果要用日志進(jìn)行性能分析葛躏,必須讓日志打印出以下幾個(gè)要素

  1. 時(shí)間
  2. 功能模塊
  3. 描述
  4. 進(jìn)程(線程)Id

我們看一個(gè)例子澈段。

在下圖中我們可以看到:

  1. 使用notepad++工具打開(kāi)log悠菜。
  2. 按照功能模塊搜索。
  3. 在下面?zhèn)兛梢钥吹竭^(guò)濾后的log败富。這個(gè)和grep的功能很像哦悔醋。
  4. 通過(guò)一行一行的查看(注意只看你過(guò)濾的模塊),發(fā)現(xiàn)在哪里耗時(shí)最多兽叮。
  5. 比如發(fā)現(xiàn)某兩行之間耗時(shí)2秒芬骄,超過(guò)預(yù)期,我們可以去看完整log鹦聪,發(fā)現(xiàn)在此之間做了哪些操作账阻。
  6. 如果是多進(jìn)程的系統(tǒng),也可以根據(jù)進(jìn)程過(guò)濾泽本。
log性能分析的例子

使用log的方法需要你可以修改源碼淘太,在關(guān)心的地方插入log(比如一些生命周期的關(guān)鍵地方,啟動(dòng)結(jié)束與顯示等等)观挎,也需要在團(tuán)隊(duì)中推行這種做法琴儿,不然log不全段化,看了也沒(méi)啥用嘁捷。

如果log非常全,就需要使用過(guò)濾工具去過(guò)濾log显熏,grep和nodepad++的過(guò)濾功能都很強(qiáng)大雄嚣。

工具

性能測(cè)試的工具很多,總體思想都是圖形化調(diào)用堆棧喘蟆,顯示占用的事件百分比缓升。

1. Flame Graphs
下面顯示的Flame Graphs可以顯示出函數(shù)占用的時(shí)間,應(yīng)該說(shuō)是非常好用蕴轨。

cpu-mixedmode-node
cpu-mixedmode-node

具體的使用方法可以查看這篇博客cpuflamegraphs

2. v8-profiler

var fs = require('fs');
var profiler = require('v8-profiler');
profiler.startProfiling('1', true);
var profile1 = profiler.stopProfiling();
profiler.startProfiling('2', true);
var profile2 = profiler.stopProfiling();

console.log(snapshot1.getHeader(), snapshot2.getHeader());

profile1.export(function(error, result) {
  fs.writeFileSync('profile1.json', result);
  profile1.delete();
});

profile2.export()
  .pipe(fs.createWriteStream('profile2.json'))
  .on('finish', function() {
    profile2.delete();
  });

profiler生成的文件可以用 node-inspector查看

Paste_Image.png

** 3.d8 **
d8工具需要自己編譯生成港谊,我們可以看看v8的的代碼,弄清楚v8工具以后橙弱,我們也可以自己寫(xiě)工具去測(cè)試性能歧寺,因?yàn)閷?shí)際上v8本身暴露了這些接口。

如果沒(méi)有d8棘脐,node也有類似的功能斜筐。

node --prof --prof_lazy app.js

我們看一下最終的結(jié)果:
下面可以看到cpu的使用情況,是不是很不錯(cuò)啊蛀缝。

Statistical profiling result from benchmarks\v8.log, (4192 ticks, 0 unaccounted, 0 excluded).

 [Shared libraries]:
   ticks  total  nonlib   name
      9    0.2%    0.0%  C:\WINDOWS\system32\ntdll.dll
      2    0.0%    0.0%  C:\WINDOWS\system32\kernel32.dll

 [JavaScript]:
   ticks  total  nonlib   name
    741   17.7%   17.7%  LazyCompile: am3 crypto.js:108
    113    2.7%    2.7%  LazyCompile: Scheduler.schedule richards.js:188
    103    2.5%    2.5%  LazyCompile: rewrite_nboyer earley-boyer.js:3604
    103    2.5%    2.5%  LazyCompile: TaskControlBlock.run richards.js:324
     96    2.3%    2.3%  Builtin: JSConstructCall
    ...

 [C++]:
   ticks  total  nonlib   name
     94    2.2%    2.2%  v8::internal::ScavengeVisitor::VisitPointers
     33    0.8%    0.8%  v8::internal::SweepSpace
     32    0.8%    0.8%  v8::internal::Heap::MigrateObject
     30    0.7%    0.7%  v8::internal::Heap::AllocateArgumentsObject
    ...


 [GC]:
   ticks  total  nonlib   name
    458   10.9%

 [Bottom up (heavy) profile]:
  Note: percentage shows a share of a particular caller in the total
  amount of its parent calls.
  Callers occupying less than 2.0% are not shown.

   ticks parent  name
    741   17.7%  LazyCompile: am3 crypto.js:108
    449   60.6%    LazyCompile: montReduce crypto.js:583
    393   87.5%      LazyCompile: montSqrTo crypto.js:603
    212   53.9%        LazyCompile: bnpExp crypto.js:621
    212  100.0%          LazyCompile: bnModPowInt crypto.js:634
    212  100.0%            LazyCompile: RSADoPublic crypto.js:1521
    181   46.1%        LazyCompile: bnModPow crypto.js:1098
    181  100.0%          LazyCompile: RSADoPrivate crypto.js:1628

性能測(cè)試工具很多顷链,有了工具以后還需要我們對(duì)需要優(yōu)化的代碼比較熟悉,仔細(xì)檢查屈梁,才能找到有可能的幾個(gè)點(diǎn)嗤练,慢慢優(yōu)化榛了,可以說(shuō)是一件很費(fèi)時(shí)間的工作。

自己寫(xiě)測(cè)試工具

上面的工具雖然好用煞抬,但是如果我們自己能寫(xiě)得化豈不是更好忽冻,所以我們看看能不能自己寫(xiě)一個(gè)。
我們先看看v8-profiler是如何做的
https://github.com/node-inspector/v8-profiler/blob/master/src/cpu_profiler.cc

 v8::CpuProfiler::StartProfiling(title);

好像v8自己有性能分析的模塊哦此疹。

我們?cè)俅蜷_(kāi)v8代碼僧诚。可以看到


v8內(nèi)部profile機(jī)制

所以仿照現(xiàn)有的工具蝗碎,我們完全可以打造出自己的工具阿湖笨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子肢预,更是在濱河造成了極大的恐慌炬守,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件边败,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡捎废,警方通過(guò)查閱死者的電腦和手機(jī)笑窜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)登疗,“玉大人排截,你說(shuō)我怎么就攤上這事》妫” “怎么了断傲?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)智政。 經(jīng)常有香客問(wèn)我认罩,道長(zhǎng),這世上最難降的妖魔是什么续捂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任垦垂,我火速辦了婚禮,結(jié)果婚禮上疾忍,老公的妹妹穿的比我還像新娘乔外。我一直安慰自己,他們只是感情好一罩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布杨幼。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪差购。 梳的紋絲不亂的頭發(fā)上四瘫,一...
    開(kāi)封第一講書(shū)人閱讀 51,488評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音欲逃,去河邊找鬼找蜜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛稳析,可吹牛的內(nèi)容都是我干的洗做。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼彰居,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼诚纸!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起陈惰,我...
    開(kāi)封第一講書(shū)人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤畦徘,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后抬闯,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體井辆,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年溶握,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了杯缺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奈虾,死狀恐怖夺谁,靈堂內(nèi)的尸體忽然破棺而出廉赔,到底是詐尸還是另有隱情肉微,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布蜡塌,位于F島的核電站碉纳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏馏艾。R本人自食惡果不足惜劳曹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望琅摩。 院中可真熱鬧铁孵,春花似錦、人聲如沸房资。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至岖沛,卻和暖如春暑始,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背婴削。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工廊镜, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唉俗。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓嗤朴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親虫溜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子播赁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Node.js是目前非常火熱的技術(shù)吼渡,但是它的誕生經(jīng)歷卻很奇特容为。 眾所周知,在Netscape設(shè)計(jì)出JavaScri...
    w_zhuan閱讀 3,615評(píng)論 2 41
  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,080評(píng)論 0 1
  • Node.js是目前非乘吕遥火熱的技術(shù)坎背,但是它的誕生經(jīng)歷卻很奇特。 眾所周知寄雀,在Netscape設(shè)計(jì)出JavaScri...
    Myselfyan閱讀 4,072評(píng)論 2 58
  • JavaScript絕對(duì)是最火的編程語(yǔ)言之一得滤,一直具有很大的用戶群,隨著在服務(wù)端的使用(NodeJs)盒犹,更是爆發(fā)了...
    不去解釋閱讀 2,415評(píng)論 1 16
  • 最近dota2的一部網(wǎng)劇《夢(mèng)想X計(jì)劃》悄悄登上了騰訊視頻急膀,這是近年來(lái)?yè)?jù)我所知的第一部有關(guān)dota2游戲的網(wǎng)劇沮协,雖然...
    悲傷的魔棒閱讀 100評(píng)論 0 0