国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

動態(tài)內(nèi)存分配導(dǎo)致影響Javascript性能的問題

2024-05-06 15:27:16
字體:
供稿:網(wǎng)友

內(nèi)存分配對性能的影響是很大的,分配內(nèi)存本身需要時間,垃圾回收器回收內(nèi)存也需要時間,所以應(yīng)該盡量避免在堆里分配內(nèi)存。不過直到最近優(yōu)化HoLa cantk時,我才深刻的體會到內(nèi)存分配對性能的影響,其中有一個關(guān)于arguments的問題挺有意思,寫在這里和大家分享一下。

我要做的事情是用webgl實現(xiàn)canvas的2d API(這個話題本身也是挺有意思的,有空我們再討論),drawImage是一個重要的函數(shù),游戲會頻繁的調(diào)用它,所以它的性能至關(guān)重要。drawImage的參數(shù)個數(shù)是可變的,它有三種形式:

drawImage(image, x, y) drawImage(image, x, y, width, height) drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

第一個版本大概是這樣實現(xiàn)的:

function Context() {}Context.prototype.drawImage3 = function(image, x, y) {  this.drawImage9(image, 0, 0, image.width, image.height, x, y, image.width, image.height);}Context.prototype.drawImage5 = function(image, dx, dy, dw, dh) {  this.drawImage9(image, 0, 0, image.width, image.height, dx, dy, dw, dh);}Context.prototype.drawImage9 = function(image, sx, sy, sw, sh, dx, dy, dw, dh) {  //DO IT}Context.prototype.drawImage = function(image, a, b, c, d, e, f, g, h) {  var n = arguments.length;  if(n === 3) {    this.drawImage3(image, a, b);  }else if(n === 5) {    this.drawImage5(image, a, b, c, d);  }else if(n === 9) {    this.drawImage9(image, a, b, c, d, e, f, g, h);  }}

為了方便說明問題,我把測試程序獨立出來:

var image = {width:100, height:200};var ctx = new Context();function test() {  var a = Math.random() * 100;  var b = Math.random() * 100;  var c = Math.random() * 100;  var d = Math.random() * 100;  var e = Math.random() * 100;  var f = Math.random() * 100;  var g = Math.random() * 100;  var h = Math.random() * 100;  for(var i = 0; i < 1000; i++) {    ctx.drawImage(image, a, b);    ctx.drawImage(image, a, b, c, d);    ctx.drawImage(image, a, b, c, d, e, f, g, h);  }}window.onload = function() {  function loop() {    test();    requestAnimationFrame(loop);  }  requestAnimationFrame(loop);}

用chrome的Profile查看CPU的使用情況時,我發(fā)現(xiàn)垃圾回收的時間比例很大,一般在4%以上。當(dāng)時并沒有懷疑到drawImage這個函數(shù),理由很簡單:

這個函數(shù)很簡單,它只是一個簡單的分發(fā)函數(shù),而drawImage9的實現(xiàn)相對來說要復(fù)雜得多。

這里看不出有動態(tài)內(nèi)存分配,也沒有違背arguments的使用規(guī)則,只是使用了它的length屬性。

加trace_opt和trace_deopt參數(shù)運行時,drawImage被優(yōu)化了,而且沒有被反優(yōu)化出來。

Chrome的內(nèi)存Profile只能看到?jīng)]有被釋放的對象,用它查看內(nèi)存泄露比較容易。這里的問題并不是泄露,而是分配了然后又釋放了,V8采用的分代垃圾回收器,這種短時存在的對象是由年輕代回收器管理器負(fù)責(zé)的,而年輕代回收器使用的半空間(semi-space)算法,這種大量短時間生存的對象,很快會耗盡其中一半空間,這時回收器需要把存活的對象拷貝到另外一半空間中,這就會耗費大量時間,而垃圾回收時會暫停JS代碼執(zhí)行,如果能避免動態(tài)內(nèi)存分配,減少垃圾回收器的工作時間,就能提高程序的性能。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 西乌珠穆沁旗| 丹东市| 玉田县| 太康县| 浦江县| 绥阳县| 安福县| 株洲县| 武胜县| 师宗县| 玛沁县| 专栏| 镇雄县| 钦州市| 闸北区| 宣化县| 宜良县| 夏津县| 福州市| 华坪县| 巴林右旗| 和顺县| 沈丘县| 日喀则市| 宝山区| 合肥市| 璧山县| 克拉玛依市| 临漳县| 朝阳县| 洪泽县| 柘荣县| 南宫市| 青龙| 射洪县| 广水市| 吉首市| 静海县| 汉寿县| 自贡市| 米脂县|