2011-10-18 52 views
1

(出於好奇純)在VB.net,我測試串聯100K串並獨自發現了一個線程在23毫秒做到了。兩個線程(每個連接50k)然後在最後加入兩個線程需要30毫秒。性能方面,在處理僅100k串聯時使用多線程似乎不是有益的。然後我嘗試了300萬字符串連接,每個處理1.5MM的兩個線程總是拆除一個處理全部300萬個線程的線程。我想在某些時候使用3個線程變得有益,然後是4,依此類推。有沒有更有效的方法來連接.NET中的數百萬個字符串?線程值得使用嗎?字符串連接和線程在.NET

At around 1MM string concatenations, it appears multiple threads can improve performance

僅供參考,這是我寫的代碼:

Imports System.Text 
Imports System.Threading 
Imports System.IO 
Public Class Form1 
    Dim sbOne As StringBuilder 
    Dim sbTwo As StringBuilder 
    Dim roof As Integer 
    Dim results As DataTable 
    Sub clicked(s As Object, e As EventArgs) Handles Button1.Click 
     results = New DataTable 
     results.Columns.Add("one thread") 
     results.Columns.Add("two threads") 
     results.Columns.Add("roof") 

     For i As Integer = 1 To 3000000 Step 100000 
      roof = i 
      Dim test() As Double = runTest() 
      results.Rows.Add(test(0), test(1), i) 
      Console.WriteLine(roof) 
     Next 

     Dim output As New StringBuilder 
     For Each C As DataColumn In results.Columns 
      output.Append(C) 
      output.Append(Chr(9)) 
     Next 
     output.Append(vbCrLf) 
     For Each R As DataRow In results.Rows 
      For Each C As DataColumn In results.Columns 
       output.Append(R(C)) 
       output.Append(Chr(9)) 
      Next 
      output.Append(vbCrLf) 
     Next 
     File.WriteAllText("c:\users\username\desktop\sbtest.xls", output.ToString) 
     Console.WriteLine("done") 

    End Sub 
    Function runTest() As Double() 
     Dim sb As New StringBuilder 
     Dim started As DateTime = Now 
     For i As Integer = 1 To roof 
      sb.Append(i) 
     Next 
     Dim result As String = sb.ToString 
     Dim test1 As Double = Now.Subtract(started).TotalMilliseconds 

     sbOne = New StringBuilder 
     sbTwo = New StringBuilder 
     Dim one As New Thread(AddressOf tOne) 
     Dim two As New Thread(AddressOf tTwo) 
     started = Now 
     one.Start() 
     two.Start() 
     Do While one.IsAlive Or two.IsAlive 
     Loop 
     result = String.Concat(one.ToString, two.ToString) 
     Dim test2 As Double = Now.Subtract(started).TotalMilliseconds 
     Return {test1, test2} 
    End Function 
    Sub tOne() 
     For i As Integer = 1 To roof/2 
      sbOne.Append(i) 
     Next 
    End Sub 
    Sub tTwo() 
     For i As Integer = roof/2 To roof 
      sbTwo.Append(i) 
     Next 
    End Sub 
End Class 
+1

「StringBuffer」可能會更好。 –

+0

嘗試從'System.Text'使用'StringBuilder'類 –

+1

這取決於您編寫代碼的方式以及您擁有的核心數量。出於好奇:這是一個研究還是現實世界的例子?也嘗試使用ThreadPool(看看異步委託和QueueUserWOrkItem)。不要忘記,線程初始化需要一些時間 - 當.NET和OS準備新線程時,您的單線程算法已經開始連接。線程不是爲了各種目的。 –

回答

2

檢查出的StringBuilder的.EnsureCapacity子程序。如果您正在進行大量的連接並且大致瞭解字符數量,則可以一次初始化stringbuilder的緩衝區,而不是讓它動態發生。你應該看到更多的改進。

http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.ensurecapacity.aspx

+0

這是很好的建議,但它不是OP問題的答案。 –

+0

酷我會去看看謝謝 – DontFretBrett

+0

這不是?他直接問「在.NET中連接數百萬個字符串是否有更高效的方法?線程是否值得使用?」。我回答了第一個問題。其他人已經指出,線程不是要走的路。 –

3

螺紋設計用於任務比字符串連接更加昂貴。

字符串連接包括分配和複製存儲器;這不是一個非常繁重的任務。
處理計算密集型任務時應使用多線程,並避免阻塞UI線程。

線程也可以是parallize等候上不同的東西有用的任務(例如,網絡IO到多個較慢的服務器或網絡與磁盤IO)

+0

或者可以並行執行的性能關鍵任務。 –

+0

@MarcinSeredynski:並行化通常只對計算綁定任務有幫助。 – SLaks

+0

這非常值得商榷。絕大多數線程僅用於異步。不要阻止用戶界面。 –