我已經在幾個地方看到,for-in循環比循環遍歷數組的速度慢......雖然我知道在sizeof(type)塊中向前移動與在場景後面迭代遍歷對象的鍵,我仍然好奇,究竟是什麼原因,它是如此之慢...爲什麼在JavaScript中輸入緩慢?
它是否必須做一個反向哈希函數來獲得密鑰,並且該過程是什麼慢?
我已經在幾個地方看到,for-in循環比循環遍歷數組的速度慢......雖然我知道在sizeof(type)塊中向前移動與在場景後面迭代遍歷對象的鍵,我仍然好奇,究竟是什麼原因,它是如此之慢...爲什麼在JavaScript中輸入緩慢?
它是否必須做一個反向哈希函數來獲得密鑰,並且該過程是什麼慢?
在任何特定引擎的情況下,真正的答案可能取決於該引擎的實現。 (如果有的話,差異的大小也會如此)。
但是,有不變量。例如,考慮:
var obj = {a: "alpha", b: "beta"};
var name;
for (name in obj) {
console.log(obj[name]);
}
var arr = ["alpha", "beta"];
var index;
for (index = 0; index < arr.length; ++index) {
console.log(arr[index]);
}
在obj
的情況下,發動機必須使用一種機制來跟蹤哪些屬性你已經遍歷,哪些還沒有,以及過濾掉不可枚舉的屬性。例如,幕後有一些迭代器對象(以及spec定義的方式,可能是臨時數組)。
在arr
的情況下,它沒有;您正在以一種非常簡單而有效的方式在您的代碼中處理這些問題。
每個循環的塊內容是相同的:對象的屬性查找。 (在後一種情況下,理論上也有一個數字到字符串的轉換。)
所以我期望唯一的非實現特定的答案是:額外的開銷。
for..each
循環使用iterators and generators。
迭代器是一個具有next()
方法的對象。 Generator是包含yield()
表達式的工廠函數。這兩個構造比一個整數索引變量更復雜。
在典型for(var i = 0; i < arr.length; i++)
循環,即在執行兩個指令幾乎所有迭代i++
和i < arr
。這可以說比進行函數調用要快得多(next()
或yield()
)。
此外,循環初始化(var i = 0
)也比用迭代器對象創建迭代器對象更快,或者調用生成器來創建迭代器。但是,它高度依賴於實現,JavaScript引擎的創建者盡其所能地加速這些常用語言功能。
我想說這種差異是如此的微不足道,以至於我可能會花時間優化代碼的其他部分。語法的選擇應該考慮代碼的可讀性和可維護性而不僅僅是性能,當性能增益如此之小以增加複雜性時。話雖如此,使用更有意義的語法,您和其他開發人員在您豐富和着名後維護您的代碼! ;)
是的,我猜想得到所有的鍵是一個相對緩慢的過程相比......沒有得到它們;)for ... in'必須首先查找鍵,而使用正常的'for'循環,你正在通過循環變量提供密鑰。 –
這是一個JSPerf測試,它顯示'for ... in'的運行與'Object.keys()'(至少在Chrome中)幾乎相同:http://jsperf.com/for-in- VS-鍵-VS-的。所以,獲取鑰匙和/或與此相關的一切都比較慢,並且從外部提供鑰匙。但它也取決於實施,就像T.J.說。 –