2009-10-08 71 views
3

比如像下面的代碼是超級慢:字符串連接是緩慢的極端當輸入大

var str:String = "" 
for (var i:Number = 0 ; i<1000000000000000000 ; ++i) { 
    str += "someLongLongLongLongLongLongLongLongLongString"; 
} 

有在Java中StringBuilder,但似乎也沒有類似AS。 那麼,你們如何處理大字符串連接?


更新:

感謝大家的回答!我剛剛編碼testing program。使用+=已經是最快...什麼是慢是把它放在一個TextArea ...

我已經投了你們中的大多數,因爲建議是有道理的:)雖然我的測試結果顯示,似乎我的問題是有點問題,因爲我要求更好的東西,那麼什麼是最好的:P

回答

2
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– 
performancetests.Strings (1 iterations)         
Player version: MAC 10,0,32,18 (debug) 
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– 
method...................................................ttl ms...avg ms 
stringsWithConcatMethod         17555 17555.00 
stringsWithPlusConcat          4972 4972.00 
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– 

我沒有,所以我只是用一千萬迭代循環在這個受虐狂:

var str:String = "" 
for (var i:Number = 0 ; i<10000000 ; ++i) { 
    str += "someLongLongLongLongLongLongLongLongLongString"; 
} 

與:

var str:String = "" 
for (var i:Number = 0 ; i<10000000 ; ++i) { 
    str = str.concat("someLongLongLongLongLongLongLongLongLongString"); 
} 

使用Grant Skinner's AS3 Performance Test Harness。String :: concat方法甚至更慢,但考慮到您的條件as3很可能會很慢。 (1次迭代結果是1次經過10000000次迭代循環)。結果讓我很驚訝。我認爲concat會更快。

+0

感謝您的測試(+1爲了那個原因:) )!你讓我寫我自己的測試程序呢!看到我的問題更新:) – 2009-10-09 15:32:42

+1

-1,在每次迭代時擴展字符串 - 無論該方法 - 是O(n^2)並且是錯誤的方法。 – orip 2010-10-07 12:54:09

5

我不能說我對ActionScript有經驗,但對於ECMAScript一般來說,我發現數組可以幫助加速字符串連接(JavaScript示例如下):

var sb = []; 
for (var i = 0; i < 10000000000; i++) { 
    sb.push('longlonglong'); 
    // In this particular case you can avoid a method call by doing: 
    //sb[i] = 'longlonglong'; 
} 
var str = sb.join(''); 
+1

+1,因爲這是真的大多數JS解釋器(儘管似乎'sb [i] ='longlonglong''更快......對於AVM2,這個技巧無法使用,無論是推送還是數組訪問...... – back2dos 2009-10-08 09:29:21

+0

吶喊,對於冗餘抱歉,沒有完全閱讀註釋行...... :) – back2dos 2009-10-08 09:36:53

+0

我剛剛發現,即使JS,'+ ='是最快的!看到我的問題更新! – 2009-10-09 15:31:17

6

是的,這變慢,即使是StringBuilder。我的問題是:爲什麼你想創建一個大小爲46 EB字節的字符串?

在某些時候,更傳統的外部存儲(即磁盤)方法成爲一個好主意,但你似乎已經通過了這一點(基於當今常用的磁盤陣列)。

我通常不會有這個問題,因爲我傾向於不使用字符串來存儲這樣的巨大事情。字符串通常用於較小的對象。你有什麼是一個相當大的數據倉庫,而不是一個名稱或地址字段:-)

+0

我知道你的意思。但有時我們沒有選擇,因爲用戶界面組件使用字符串... – 2009-10-09 15:29:59

2

兩個東西一般使操作這樣的慢:

  • 字符串增長了分配給它的內存,因此它必須重新分配。這涉及堆內存管理器,並複製內容。隨着內容的增長,這意味着它被複制了很多,並且內存系統必須非常努力。
  • 如果字符串未以某種方式存儲,這意味着其長度可用作O(1)操作,則串聯首先必須遍歷整個字符串以查找長度,即開始連接的位置。這意味着每個單獨的串聯花費的時間與目標字符串的長度成正比。

我敢肯定,其中至少有一個擊中了你(後者可能不會,不知道字符串是如何在ActionScript內部表示的)。

+0

+1 ...第二個不是AVM2(也不是AVM1)... – back2dos 2009-10-08 09:25:23

2

您在這裏進行類型濫用...:D ...在AVM2上,字符串是用於文本表示的......它們總是unicode,這就是爲什麼它們需要每個字符超過2個字節...所以它們不適合存儲i-will-make-your-heap-explode大小的ascii序列......如果你真的想要操縱一大堆數據,那麼去尋找flash.utils::ByteArray ......並不是說它特別快,但它在語義上更正確,並具有較低的內存佔用...加上它有原生的壓縮方法,這是我在你的情況下高度推薦...:P

+0

感謝您的建議!這就是我原來的想法。但是我發現String的'+ ='是最快的:P 因爲我想顯示文本,所以在任何情況下都需要創建一個String ... – 2009-10-09 15:36:21