2009-09-03 108 views
21

我正在讀這本書 - 專業的Javascript的Web開發人員提到字符串連接的開發人員比使用數組來存儲字符串,然後使用連接方法來創建最終的字符串。出於好奇,我做了幾個測試在這裏看到多少時間就可節省,這是我得到了什麼 -字符串連接vs字符串緩衝區在Javascript中

http://jsbin.com/ivako

不知何故,火狐通常會產生幾分相似倍兩種方式,但在IE瀏覽器,串連接速度要快得多。所以,現在這個想法可以被認爲是過時的(瀏覽器可能已經改進了,因爲?

+0

我剛剛在IE 7(jsbin.com/ivako)中試過你的例子,它似乎與你所說的相反。我得到:與加號級聯:92829毫秒與StringBuffer級聯:125毫秒。 在同一臺機器上的Firefox 3.5中,我得到串聯加上:110毫秒 與StringBuffer串聯:113毫秒 – 2009-09-03 00:58:15

+0

這是奇特的。自從我在本地運行腳本以來,我以爲自己得到的結果是扭曲的,所以我放上了jsbin。還是一樣。我使用IE8和Firefox 3.5。我將在虛擬PC上的IE7上嘗試此操作。 – Dhana 2009-09-03 01:01:23

+0

92829毫秒?那1分32秒。你確定? – bucabay 2009-09-03 11:12:51

回答

26

**編輯:我假設人們仍然在查看這篇文章 - 但它已經3+年,所以只需查看以下信息即可:http://jsperf.com/string-concatenation/14

查看此帖子的變化以查看它曾經說過的內容。

+0

很好的答案,但如果串被串聯明顯延長(至少500字)差異會很明顯,無論什麼樣的電腦運行它 – Rodrigo 2009-09-03 01:17:47

+1

** **的TraceMonkey,不Trackmonkey:) – kangax 2009-09-03 04:41:11

+0

拼寫錯誤:) – 2009-09-04 06:10:36

4

即使它是真實的,並且join()比串聯更快也沒關係,我們在這裏談論的是微小的毫秒數是完全可以忽略不計。

我總是喜歡結構良好,易於閱讀在顯微鏡的性能提升代碼,我覺得用串聯看起來更好,更容易閱讀。

只是我的兩分錢。

+5

多次發生的循環內部的毫秒數並不總是可以忽略的。它可以添加到秒,幾天或幾年 - 取決於應用程序,我不相信你不知道這一點。你的兩美分毫無價值。 – DaveWalley 2014-04-23 21:26:07

+0

完全同意w/@DaveWalley ...如果您不考慮[複雜性](https://en.wikipedia.org/wiki/Big_O_notation),即算法的運行時間/空間,這可能意味着順利和滯後的反應之間的區別。我認爲你的兩分錢實際上是值得兩分錢的債務。 – 2015-06-25 00:26:54

+1

我認爲Richard Knop有一個總有效點。在項目的早期階段,可讀性很重要。只要你不在i> 1000循環中,連接就沒有問題。請不要因爲這個'過早優化'陷阱...這是一個衆所周知的反模式,並導致我的經驗最悲傷。 – 2016-03-03 11:54:14

1

我實際上在這方面有一些經驗,因爲我的主要產品是一個大型的IE瀏覽器,它爲了構建XML文檔以發送到服務器而進行了大量的字符串連接。例如,在最糟糕的情況下,頁面可能會有5-10個iframe,每個iframe有幾百個文本框,每個文本框都有5-10個expando屬性。

對於像我們的保存功能一樣,我們遍歷每個選項卡(iframe)和該選項卡上的每個實體,將每個實體的所有expando屬性拉出來,並將它們全部放入一個巨大的XML文檔中。

在分析和改進我們的保存方法時,我們發現在IE7中使用字符串連接要比使用字符串數組方法慢很多。其他一些關注點是訪問DOM對象expando屬性非常慢,所以我們將它們全部放入JavaScript數組中。最後,生成JavaScript數組本身實際上最好是在服務器上完成,然後將其作爲文字控件寫入頁面,然後在頁面加載時執行。

+0

我在其中一個應用程序中遇到類似問題,我決定今天嘗試這種方法 - whaddya說 - IE7的改進絕對可見。 – Dhana 2009-09-03 03:08:52

2

在我的系統(IE 8在Windows 7)的StringBuilder在該測試非常約70%-100%範圍內的時間 - 也就是說,它是不穩定的 - 雖然均值的約95%的正常追加。

雖然很容易,現在只是說「過早優化」(我懷疑,在幾乎所有情況下它是)有些事情值得考慮:

反覆字符串連接問題就來了重複內存分配和重複數據副本(高級字符串數據類型可以減少/消除大部分內容,但現在讓我們繼續假設一個簡單的模型)。由此可以提出一些問題:

  • 使用什麼內存分配?在天真的情況下,每個str + = x都需要分配str.length + x.length新內存。例如,標準C malloc是一個相當差的內存分配器。 JS的實現在多年來經歷了變化,其中包括更好的內存子系統。當然,這些變化並不止於此,而是觸及現代JS代碼的所有方面。因爲現在實施方式可以在某些任務已經慢得令人難以置信並不一定意味着同樣的問題仍然存在,或以相同的程度。

  • 與Array.join執行上面是非常重要的。如果它在構建它之前不爲最終字符串預先分配內存,那麼它只會節省數據拷貝的成本 - 這些日子主內存有多少GB/s? 10,000 x 50幾乎沒有限制。與POOR MEMORY ALLOCATOR的智能Array.join操作預計可以更好地簡化執行,因爲重新分配的數量會減少。隨着分配成本的降低,這種差異預計會最小化。

  • 微基準代碼可根據如果JS引擎創建每每個唯一字符串文字或不是一個新的對象是有缺陷的。 (這會偏向Array.join方法,但通常需要考慮)。

  • 基準確實是一個微基準:) 增加生長尺寸應具有的性能基於任何或所有(然後一些)上述條件的影響。通常很容易顯示有利於某種方法的極端情況 - 預期的用例通常更重要。

雖然,坦白地說,任何形式的理智串樓,我只想用正常的字符串連接,直到它被確定爲一個瓶頸,如果有的話這樣的時刻。

我會重新閱讀本書中的上述聲明,看看作者是否確實有意圖調用諸如「對於非常大的字符串」或「瘋狂量的字符串操作」或「在JScript中」/IE6「等等...如果不是,那麼這樣的表述就像」插入排序是O(n * n)「一樣有用[[實現成本取決於數據的狀態和當然的大小] 。

而且免責聲明:代碼的速度取決於瀏覽器,操作系統,底層硬件,月球引力,當然,你的電腦是如何看待你的。

-1

好吧,這在這裏關於一個相關的模塊:通過使用

var buffer = new String.Buffer(); 
buffer.append("foo", "bar"); 

這是哪門子最快落實的

http://www.openjsan.org/doc/s/sh/shogo4405/String/Buffer/0.0.1/lib/String/Buffer.html

這是創建字符串緩衝區的有效手段,我知道的字符串緩衝區。首先,如果你正在實現字符串緩衝區,不要使用push,因爲這是一個內置方法,並且速度很慢,因爲一次push迭代遍歷整個arguments數組,而不是添加一個元素。

這一切真的取決於加入方法的實現,join方法的一些實施很慢,有些是比較大的。

+0

你是否有鏈接指出推送方法很慢? – Prestaul 2009-09-03 01:59:21

+0

http:// openjsan。org/doc/j/jh/jhuni/StandardLibrary/1.81/lib/Array.html 您必須處理__proto__以及參數Array的長度,這兩件事情不應該是必需的。 http://groups.google.com/group/jquery-dev/browse_thread/thread/5019fa537c8d3595 – jhuni 2009-09-05 06:58:58

2

原則上這本書是正確的。加入一個數組應該是很多快於重複連接到同一個字符串。作爲不可變字符串的簡單算法,它顯然更快。

訣竅是:JavaScript作者,主要是非專業的軟件開發人員,他們在野外編寫了大量代碼,使用連接方式,而使用像array-join這樣的方法的代碼相對較少。結果是瀏覽器作者可以通過迎合和優化「不好」,更常見的串聯選項,在平均網頁上獲得更好的速度提升。

這就是發生了什麼事。較新的瀏覽器版本有一些相當多毛茸茸的優化工具,它們可以檢測你何時進行連接加載,並且可以對它進行攻擊,使得它在內部更像一個數組連接,工作速度幾乎相同。

0

正如我們所知,並非所有的瀏覽器都是平等的。因此,保證不同區域的性能會因瀏覽器而異。

除此之外,我注意到和你一樣的結果;然而,去除不必要的緩衝級,只是直接使用數組和10000字符串後,結果甚至更緊/一致(在FF 3.0.12):http://jsbin.com/ehalu/

除非你正在做的一個很大字符串連接,我會說這種類型的優化是一個微型優化。在限制DOM reflowsqueries(通常使用document.getElementbyById/getElementByTagName),實現AJAX結果的緩存(在適用的情況下)以及利用事件冒泡(某處存在鏈接,我現在找不到它)時,可能會更好一些。 。

+0

我試過你的腳本,不幸的是它在Firefox 3.5中保持超時。 – Dhana 2009-09-04 15:58:42

+0

更重要的是瀏覽器與其版本之間的性能差異。 – 2009-09-04 19:35:51