2010-11-02 81 views
5

當我讀到Guido van Rossum的散文An Optimization Anecdote時,它開始了。爲什麼array.map(String.fromCharCode)這麼慢?

決定嘗試在JavaScript中同樣的事情,我計時了以下內容:

numbers.map(function(x){ return String.fromCharCode(x); }); 

這是相當快了,但爲什麼不能完全消除匿名函數,並直接傳遞使用String.fromCharCode映射():

numbers.map(String.fromCharCode); 

我計時,並...... 這是慢〜100倍比以前的版本。怎麼來的?

以某種方式直接將此本機函數傳遞給Array.map()比將其包裝到另一個函數內並將其傳遞給Array.map()要慢。

  • 這不是特定於瀏覽器:在Chrome,Firefox和Opera中進行測試。

  • 它不是特定於map():嘗試forEach(),它的行爲相似。

  • 它不是特定於內置函數:嘗試Math.round()和Math.sin() - 結果如人們所期望的那樣:直接將函數傳遞給Array.map()是一點點比使用中間匿名函數要快。

看來問題出在String.fromCharCode上。

這是怎麼回事?

PS。最初在Hacker News thread提出了這個問題,但由於相關文章是關於Python的,我認爲它會在這裏發佈時更多地暴露於JavaScript開發人員。對不起,交叉發帖。

回答

5

我自己找到了解決方案。

問題是,String.fromCharCode()接受多個參數,而Array.map()也將多個參數傳遞給回調函數。因此,代碼:

numbers.map(String.fromCharCode); 

其實就是等同的:

numbers.map(function(x, y, z){ return String.fromCharCode(x, y, z); }); 

從中可以很明顯它爲什麼這麼慢。此外它也是越野車。

+1

我剛剛發佈了相同的答案。預期的結果是不同的,因爲'String.fromCharCode'構造了所有傳入參數的返回字符串(在這種情況下,由於第三個參數不是數字,因此傳入的前兩個參數)。 – 2010-11-02 14:21:41