3

爲什麼這個新代碼比我的舊代碼慢?

我已經取代了我在與我的預期有更好的表現了一些新的代碼的性能問題的一些代碼的問題。相反,它表現更差。我想了解爲什麼會出現這種情況,以便我可以使用chrome的V8運行時而不是反對它。

背景

我的代碼是一個基於瀏覽器的遊戲。在正常操作期間,許多xy座標在函數之間傳遞。之前我「固定」的東西這樣的例子看起來是這樣的:

function doSomething1(x,y) { 
    /* Do work here */ 
    return {x: newx, y: newy}; 
} 

function doSomething2(x,y) { 
    /* Do work here */ 
    return {x: newx, y: newy}; 
} 

function doSomething3(x, y) { 
    var result1 = doSomething1(x, y); 
    var result2 = doSomething2(result1.x, result1.y); 

    /* Do work here */ 
    return {x: newx, y: newy}; 
} 

你的想法..大量的相互調用,返回小匿名對象與XY屬性和採摘值超出它們的功能。

當我的遊戲運行時,它有垃圾收集問題。內存圖非常尖銳,幀速率不平滑。爲了緩解這個問題,我決定重新寫我的代碼,以便它遵循了這一模式:

function doSomething(x,y,out) { 
    /* Do work here */ 
    out[0] = newx; 
    out[1] = newx; 
} 

var xy = [0,0]; /* Some 2-length array for results */ 
doSomething(5,6,xy); 
/* 'Return' value in xy */ 

這樣,只有一個「分配」和它調用的函數下來的數值數組中替換鏈。

這確實有平滑內存分配圖的效果。它也有將我的幀頻降低50%的意想不到的副作用!

這是爲什麼呢?我可能會繞過哪些優化?我怎樣才能更好地編寫這段代碼來處理V8運行時?

更新

進一步的調查表明,該代碼事實上不是慢50%。只有當新代碼託管在127.0.0.1和Internet上的舊代碼時纔會變慢。這很奇怪,但不是同一個問題。我將結束這個問題。

+0

一個可能的原因是,你使用'out'數組和動態大小。你可以嘗試創建一個固定大小的數組,並讓我們知道結果:)你還沒有提到你有多少元素,你可以添加這些信息嗎? – Warlock 2013-02-28 19:12:45

+0

「不成熟的優化是萬惡之源」 - Donald Knuth – Warlock 2013-02-28 19:21:04

回答

0

當你寫

out[0] = newx 

V8只知道要分配一個新對象與「0」領域,堅持newx進去。當你繼續

out[1] = newy 

它必須跟蹤它剛剛分配的對象,併爲'1'字段分配更多的空間。這比{x: newx, y:newy}貴很多,因爲在後一種情況下,V8已經知道將會有多少個字段。

我對優化JavaScript或您的遊戲瞭解不多,因此我很難進一步提出建議。希望你已經看過算法問題,現在正試圖做一些微調 - 算法是可以做出重大改進的地方。