2012-04-23 32 views
2

我正在製作將圖像轉換爲文本RRR GGG BBB 字符串數組的應用程序。查找連接巨大字符串的更快方法

它對於小圖像運行速度非常快,但是當輸入圖像的像素數非常高時,應用程序會逐漸減慢。

應用程序運行x,y循環遍歷輸入圖像的所有像素,掃描每個像素並將其RGB格式的值添加到最終字符串中,最終字符串將在整個圖像掃描後保存爲文本。

在內置分析器的幫助下,我發現System.String.Concat(string,string)需要越來越多的時間,最終的字符串越大。

然後我嘗試了一個臨時字符串,它將保存1行的計算結果,並在進入下一行之前將其添加到最終字符串中。現在它的工作速度提高了十倍,但接近尾聲的性能下降了。

但最終我的所有測試圖像都比真實的圖像要小。如何保持連接速度更高,圖像更大?

+0

你對字符串做了什麼?你可以保存/發送一部分嗎? – 2012-04-23 12:03:57

回答

7

使用System.Text.StringBuilder

var sb = new StringBuilder(); 
sb.Append(r); 
sb.Append(g); 
sb.Append(b); 

string result = sb.ToString(); 

這個類是專門爲快速字符串連接。我不知道什麼更快(一般情況下)。

+4

打開鏈接並向下滾動:) – 2012-04-23 12:04:30

+0

就是這樣,現在它運行得更快。巨大的圖像也被處理得足夠快。 – user1306322 2012-04-23 12:09:09

+1

爲了獲得最佳性能,如果您大致瞭解所需的大小,請將其包含在構造函數中,例如'new StringBuilder(sizeEstimate)'。然後它會預先分配估計的大小,而不是從(可能小得多)的默認大小開始調整太大。 – Will 2012-04-23 12:18:41

2

使用String.Join("", myarray);

4

爲了詳細說明@ abatishchev的回答是:

連接字符串時,你實際上是創建每次關聯一個新的字符串實例,讓你在成千上萬的分配(百萬?)細長的琴絃。 但是,StringBuilder使用內部字符緩衝區來管理字符串的生成過程,並避免這些頻繁的分配。

用法是這樣的:

StringBuilder sb = new StringBuilder(); 
foreach (Pixel pixel in myPixels) 
{ 
    sb.Append(ConvertToString(pixel)); 
} 

string myString = sb.ToString(); 
0

使用StringBuilder這樣的:

//add reference 
using System.Text 

//create string builder 
StringBuilder sb = new StringBuilder(); 
//add items to it 
sb.Append("some text"); 
sb.Append(" more text"); 
3

正如大家說,是的,使用StringBuilder。

如果你已經有了字符串一些集合的形式來連接,String.Join()被證明是更快。

請注意。

+0

根據Reflector的說法,如果String.Join更快,考慮到它在內部使用StringBuilder的事實,那將是一件令人驚訝的事情。編輯:罷工。似乎Join的一些重載使用它們自己的不安全的實現,有些使用StringBuilder。有趣。 – 2012-04-23 12:44:11

+2

我挖掘了一些string.Join,看起來如果你有一個現有的*數組*的字符串('string []'),string.Join將使用一個內部的不安全的實現。但是,如果您有任何其他字符串集合('IEnumerable '重載)或'object []',則string.Join將在內部使用StringBuilder。顯然,當他們知道字符串按順序排列在陣列中時,他們可以獲得一些性能優勢。 – 2012-04-23 12:50:00

+0

有道理。無論哪種方式,string.Join只能改進。但是,當然,事先不在集合中--StringBuilder是要走的路。 – SimpleVar 2012-04-23 12:50:51

0

StringBuilder設計用於處理龐大而複雜的字符串。