0

我正在尝试使用并行处理来根据其内容分离数据。

在下面的示例中,我生成随机数,如果满足 a 条件,我想将它们存储到数据表中。

令我失望的是,顺序 for 的工作速度比并行快。

使并行工作更快可行吗?

Imports System.Random
Imports System.Threading
Imports System.Threading.Tasks

Public Class Form1
    Public No As Integer = 5
    Public DT(No) As DataTable
    Public S(No) As String
    Public StartTimer As DateTime
    Private Sub ParrallelProc_Btn_Click(sender As Object, e As EventArgs) Handles ParrallelProc_Btn.Click
        For j = 1 To No
            DT(j).Rows.Clear()
        Next
        StartTimer = Now
        For k = 1 To 10000
            Parallel.For(1, No + 1, Sub(i)
                                        Dim CurrentNo As String = CStr(Math.Round(Rnd() * 1000000, 0))
                                        If CurrentNo.Contains(S(i)) Then DT(i).Rows.Add(CurrentNo)
                                    End Sub)
        Next
        Dim Interval = Now.Subtract(StartTimer).TotalSeconds
    End Sub

    Private Sub SequentialProc_Btn_Click(sender As Object, e As EventArgs) Handles SequentialProc_Btn.Click
        For j = 1 To No
            DT(j).Rows.Clear()
        Next
        StartTimer = Now
        For k = 1 To 10000
            For l = 1 To No
                Dim CurrentNo As String = CStr(Math.Round(Rnd() * 1000000, 0))
                If CurrentNo.Contains(S(l)) Then DT(l).Rows.Add(CurrentNo)
            Next
        Next
        Dim Interval = Now.Subtract(StartTimer).TotalSeconds
    End Sub
End Class
4

2 回答 2

1

首先,不要吹嘘,但我的 PC 在 160 毫秒内运行并行,在 40 毫秒内运行顺序。

创建线程有一些开销,并且只有 5 个线程是不必要的 - 你不妨只做 5 件事。尤其是像你所拥有的那样轻巧的东西。并行化是为了同时执行多个长时间运行的任务。

最终,一旦您克服了线程开销,并行循环会更快。我已经测试了增加No,这发生在 100 左右。

Public No As Integer = 100
Public DT(No) As DataTable
Public S(No) As String
Public StartTimer As DateTime
Private iterations As Integer = 10000

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    For i = 1 To No
        DT(i) = New DataTable()
        DT(i).Columns.Add()
        S(i) = (i + 1).ToString()
    Next
End Sub

Private Sub ParallelProc_Btn_Click(sender As Object, e As EventArgs) Handles ParallelProc_Btn.Click
    clearDT()
    Dim sw As New Stopwatch()
    sw.Start()
    For k = 1 To iterations
        Parallel.For(
            1,
            No + 1,
            AddressOf process)
    Next
    sw.Stop()
    MessageBox.Show(sw.ElapsedMilliseconds)
End Sub

Private Sub SequentialProc_Btn_Click(sender As Object, e As EventArgs) Handles SequentialProc_Btn.Click
    clearDT()
    Dim sw As New Stopwatch()
    sw.Start()
    For k = 1 To iterations
        For i = 1 To No
            process(i)
        Next
    Next
    MessageBox.Show(sw.ElapsedMilliseconds)
End Sub

Private Sub clearDT()
    For j = 1 To No
        DT(j).Rows.Clear()
    Next
End Sub

Private Sub process(i As Integer)
    Randomize()
    Dim CurrentNo As String = CStr(Math.Round(Rnd() * 1000000, 0))
    If CurrentNo.Contains(S(i)) Then DT(i).Rows.Add(CurrentNo)
End Sub

我还将操作移至可以由两个例程调用的 Sub。重用代码不仅可以节省时间和空间,还可以确保您只是比较方法,而不是例程。

您还应该Randomize()在使用之前调用Rnd(). 请参阅https://msdn.microsoft.com/en-us/library/y66ey2hh(v=vs.110).aspx

更好的测试是在process()方法中加入一些实质性的东西,比如 a Thread.Sleep(1),然后使用Noand iterations。你会发现并行睡眠比顺序睡眠效率高得多。

于 2017-05-11T20:37:51.507 回答
0

将较小的循环放入较大的循环中,它应该使并行循环比顺序循环快得多。

Imports System
Imports System.Diagnostics
Imports System.Threading.Tasks

Public Module Module1
Public Sub Main()

    Dim Rnd as New Random()
    Dim _sw as new Stopwatch

    _sw.Restart()
    For k = 1 To 1000
        Parallel.For(1, 6, Sub(i)
            Dim CurrentNo As Double = Rnd.Next()
            ' Do other stuff
        End Sub)
    Next

    Console.WriteLine(_sw.Elapsed) 
    ' >> took 00:00:00.0659017 on dotnetfiddle.net

    _sw.Restart()
    Parallel.For(1, 1000+1, Sub(k)
        For i as Integer = 1 to 5
            Dim CurrentNo As Double = Rnd.Next()
            ' Do other stuff
        Next
    End Sub)

    Console.WriteLine(_sw.Elapsed)
    ' >> took 00:00:00.0009715 on dotnetfiddle.net

End Sub

End Module
于 2017-05-11T20:52:55.563 回答