C# NET中的字符串连接和线程
(出于好奇)在VB.net中,我测试了连接100k字符串,发现仅一个线程就在23毫秒内完成了连接。两个线程(每个线程连接50k)然后在末尾连接这两个线程需要30毫秒。就性能而言,在仅处理100k连接时,使用多线程似乎没有什么好处。然后我尝试了300万个字符串连接和两个线程,每个线程处理1.5毫米的数据,但总是破坏一个线程处理所有300万个数据。我想象在某个时候,使用3个线程变得有益,然后使用4个线程,依此类推。有没有更有效的方法在.NET中连接数百万个字符串?线程值得使用吗 仅供参考,这是我写的代码:C# NET中的字符串连接和线程,c#,vb.net,multithreading,string,concatenation,C#,Vb.net,Multithreading,String,Concatenation,(出于好奇)在VB.net中,我测试了连接100k字符串,发现仅一个线程就在23毫秒内完成了连接。两个线程(每个线程连接50k)然后在末尾连接这两个线程需要30毫秒。就性能而言,在仅处理100k连接时,使用多线程似乎没有什么好处。然后我尝试了300万个字符串连接和两个线程,每个线程处理1.5毫米的数据,但总是破坏一个线程处理所有300万个数据。我想象在某个时候,使用3个线程变得有益,然后使用4个线程,依此类推。有没有更有效的方法在.NET中连接数百万个字符串?线程值得使用吗 仅供参考,这是我写
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
线程是为比字符串连接更昂贵的任务而设计的 字符串连接涉及分配和复制内存;这不是一项非常耗费精力的任务。
处理计算密集型任务时应使用多线程,以避免阻塞UI线程
线程还可以用于并行化等待不同任务的任务(例如,多个慢速服务器的网络IO,或网络与磁盘IO)线程是为比字符串连接更昂贵的任务而设计的 字符串连接涉及分配和复制内存;这不是一项非常耗费精力的任务。
处理计算密集型任务时应使用多线程,以避免阻塞UI线程
线程还可以用于并行化等待不同任务的任务(例如,网络IO到多个慢速服务器,或网络与磁盘IO)查看StringBuilder上的.EnsureCapacity子例程。如果您正在进行大量连接,并且大致知道字符数,则可以一次性初始化stringbuilder的缓冲区,而不是让它动态发生。你应该看到更多的改进
查看StringBuilder上的.EnsureCapacity子例程。如果您正在进行大量连接,并且大致知道字符数,则可以一次性初始化stringbuilder的缓冲区,而不是让它动态发生。你应该看到更多的改进
使用
StringBuffer
可能会更好。请尝试使用系统中的StringBuilder
类。Text
这取决于您编写代码的方式以及拥有的内核数。出于好奇:这是一个研究还是现实世界的例子?还可以尝试利用线程池(查看异步委托和QueueUserWOrkItem)。不要忘记线程初始化需要一些时间——当.NET和OS准备新线程时,您的单线程算法已经开始连接。线程不是为每一个目的而存在的。@汉斯潘太糟糕了,你考虑好奇心和实验“什么都不做”我用的是线程,而不是你:使用线程。。使用StringBuffer
可能会更好。请尝试使用系统中的StringBuilder
类。Text
这取决于您编写代码的方式以及拥有的内核数。出于好奇:这是一个研究还是现实世界的例子?还可以尝试利用线程池(查看异步委托和QueueUserWOrkItem)。不要忘记线程初始化需要一些时间——当.NET和OS准备新线程时,您的单线程算法已经开始连接。线程不是为每一个目的而存在的。@汉斯潘太糟糕了,你想好奇心和实验“什么都没做”,“我说的是线程,而不是你:”使用Too.Con()。这是一个很好的推荐,但是,它不是OP问题的答案。不是吗?他直接问道:“有没有更有效的方法在.NET中连接数百万个字符串?线程值得使用吗?”。我回答了第一个问题。其他人已经指出线程不是解决问题的方法。这是一个很好的建议,但是,它不是OP问题的答案。不是吗?他直接问道:“有没有更有效的方法在.NET中连接数百万个字符串?线程值得使用吗?”。我回答了第一个问题。其他人已经指出线程不是解决问题的方法。@Marcineredynski:并行化通常只对计算绑定的任务有帮助。这很有争议。绝大多数线程仅用于异步。“不要阻塞UI。@汉森:我在第二段中说过。啊,我被神秘的第一句话难住了:)也许你应该交换它们?@Marcineredynski:并行化通常只对计算任务有用。这很有争议。绝大多数线程仅用于异步。“不要阻塞用户界面”。@HansPassant:我在第二段中说过。啊,我被神秘的第一句话卡住了:)也许你应该交换它们?