gpt4 book ai didi

.net - 简单线程速成类?

转载 作者:行者123 更新时间:2023-12-01 13:00:36 25 4
gpt4 key购买 nike

我正在测试线程的想法,但目前只在非常关键的地方进行。线程几乎为任何事物增加了相当迷人的复杂性,但对于 .NET,System.Threading 中的线程似乎有很多选择。我想知道哪个最适合处理字符串操作。

考虑将一个复杂 字符串提供给自定义对象。该对象当前在某个点拆分字符串,并将第一部分提供给一个函数,然后当该函数完成时,将字符串的另一半提供给第二个函数。这两个函数彼此没有依赖关系,因此应该是线程化的良好候选者,以便两个函数可以同时处理字符串的每一段。

标题前的例子:

Public Sub ParseString(ByVal SomeStr As String)
If String.IsNullOrWhitespace(SomeStr) Then
Throw New ArgumentNullException("SomeStr")
End If

' Assume that ParsedFirstString is a boolean that is set to
' True if the call to ParseFirstString completes successfully.
' Ditto for ParsedSecondString.

Dim MyDelimiter As Char = "|"c
Dim SomeStrArr As String() = SomeStr.Split({MyDelimiter}, 2)

Call Me.ParseFirstString(SomeStrArr(0))

If Me.ParsedFirstString = False Then
Throw New ArgumentException("Failed to parse the first part of the string.")
End If

Call Me.ParseSecondString(SomeStrArr(1))

If Me.ParsedSecondString = False Then
Throw New ArgumentException("Failed to parse the second part of the string.")
End If
End Sub




这工作正常,在我的多核系统上的计时循环内测试,我可以在 ~140ms-170ms 内执行它 1,000 次(平均 ~1,200ms+ 如果 10,000 次) .这是一个可以接受的速度,如果我不能让线程发挥得很好,那么我会继续前进。但是我在看了一个 threading example 之后尝试了一种线程方法以及关于调用 thread with parameters 的 SO 问题并以类似于以下的代码结束:

Public Sub ParseString(ByVal SomeStr As String)
If String.IsNullOrWhitespace(SomeStr) Then
Throw New ArgumentNullException("SomeStr")
End If

Dim MyDelimiter As Char = "|"c
Dim SomeStrArr As String() = SomeStr.Split({MyDelimiter}, 2)

Dim FirstThread As New Thread(Sub() Me.ParseFirstString(SomeStrArr(0))
Dim SecondThread As New Thread(Sub() Me.ParseSecondString(SomeStrArr(1))

FirstThread.Priority = ThreadPriority.Highest
SecondThread.Priority = ThreadPriority.Highest

Call FirstThread.Start()
Call SecondThread.Start()

If Me.ParsedFirstString = False Then
Throw New ArgumentException("Failed to parse the first part of the string.")
End If

If Me.ParsedSecondString = False Then
Throw New ArgumentException("Failed to parse the second part of the string.")
End IF
End Sub




这个问题是字符串的第一部分或第二部分的解析可以在两者完成之前完成,这会绊倒其中一个两个异常(exception)。所以我进一步环顾四周,发现我可以使用 Join 方法来等待两个线程完成。这解决了异常的绊倒问题,但它大大增加了执行时间。执行上述函数 1,000 次并计时,现在平均运行时间可达 ~3,700 毫秒。似乎线程不适合这种任务。

但似乎还有其他线程机制,包括 ThreadPools 和 BackgroundWorkers。可能其他我还没有查过(我几个小时前才开始弄乱这个)。

社区对此类任务的线程有何看法?我第一次尝试线程有什么问题?

仅供引用,我不会更新任何 UI 组件,也不会将结果写入任何类型的存储介质。





结论:

看来我的字符串解析函数比我想象的要好得多。 Parallel Class 都试过了和 Task Class ,如果我测试一个 10,000 次迭代循环,然后是单线程,我的测试数据大约为 ~1,220ms-1,260ms。如果我什至实现基本的 Parallel.Invoke() 以将解析拆分为两个并行线程,我会将该计时循环填充到额外的 ~300ms(可能是由于匿名委托(delegate)的开销,但似乎没有办法解决这个问题)。这是在 Core2 Q9550 Yorkfield 上,未超频,95W 处理器,用于比较。

获胜的选择是为这个特定的代码区域保持单线程。感谢所有参与的人!

最佳答案

我建议使用 TPL 类,例如 ParallelTask

您的代码是否受益于并行执行,您需要在特定机器上进行基准测试并找出答案。这是最好的方法。相同的代码在一台机器上会减慢执行速度,但在另一台机器上会加快很多。基本上取决于 CPU(内核数、超线程等)、算法和并行任务数。

如果您使用 TPL,您的代码看起来会很简单:

    Call Parallel.Invoke(
Sub()
Me.ParseFirstString(SomeStrArr(0))
End Sub,
Sub()
Me.ParseFirstString(SomeStrArr(1))
End Sub)

对不起,我不擅长 VB.NET 语法。可能有办法让它更短。

关于.net - 简单线程速成类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6245714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com