【问题标题】:Sort 3 x one dimensional arrays in parallell并行排序 3 x 一维数组
【发布时间】:2013-08-14 00:38:15
【问题描述】:

我有 3 x 一维整数类型数组,每个数组的长度相同(介于 5 到 2000 万个值之间),我想通过第二个数组对它们进行并行排序(即保持相对位置),然后第三个数组,然后是第一个数组。有人对在 vb.net 中执行此操作的最有效方法有任何想法吗?

如果有帮助,第一个数组只是初始位置的记录(一旦完成各种计算,三个数组将重新排序到此顺序)。我需要对它们进行排序以确定第二个和第三个数组的唯一组合的数量(组合由数组中的位置确定 - 在下面的示例中,组合是 (0-1-4), (1-1- 6)等)。一旦确定了,我将根据第一个数组将它们返回。

我查看了 array.sort,但它只涵盖了 2 个并行数组。我有点担心将值放在元组(或任何其他格式)中,因为在处理之前转换 5 到 2000 万条记录时(我假设 - 也许不是)会产生很大的开销。

例如:

Record Number Array: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

Link Array: {1, 1, 2, 1, 1, 2, 2, 2, 1, 2}

Line Number Array: {4, 6, 3, 5, 6, 7, 3, 2, 3, 4}

按第二个、第三个、第一个数组排序/排序后,预期输出将是:

Record Number (1st Array): {8, 0, 3, 1, 4, 7, 2, 6, 9, 5}

Link Array (2nd Array): {1, 1, 1, 1, 1, 2, 2, 2, 2, 2}

Line Number Array (3rd Array): {3, 4, 5, 6, 6, 2, 3, 3, 4, 7}

Array.sort 只允许您并行排序 2 个数组,我对 LinQ 中可用的选项有点困惑。

有人对解决此问题的最佳方法有任何建议吗?

干杯,

【问题讨论】:

  • Array.Sort 并行排序?
  • @Magnus Array.Sort 方法(数组,数组)msdn.microsoft.com/en-us/library/85y6y2d3.aspx
  • @AndrewMorton 我在那里找不到任何关于它并行的信息。
  • @Magnus 不是并行线程,而是在对array1中的项进行排序时,同时对array2中具有相同索引的项进行交换,即并行。
  • “转换 5 到 2000 万条记录时,开销会很大” - 你测试过这个假设吗?

标签: vb.net sorting


【解决方案1】:

我认为您可以获得链接阵列的备份。然后用 Record Array 对 Link Array 进行排序,然后可以用 Line Number Array 对未排序的 Link Array 进行排序。可以试试吗?

【讨论】:

    【解决方案2】:

    您没有说是否要在时间或空间方面高效,但是将 2000 万条记录从数组传输到列表大约需要 3 秒,然后对它们进行排序大约需要 30 秒,使用更少超过 1GB 的内存。在我的电脑上。

    Option Infer On
    Module Module1
    
    Class Grouped
        Property RecNo As Integer
        Property Link As Integer
        Property LineNo As Integer
    
        Public Overrides Function ToString() As String
            Return String.Format("({0}, {1}, {2})", Me.RecNo, Me.Link, Me.LineNo)
        End Function
    
    End Class
    Sub Main()
        ' First try with the test data to show the correct result is obtained
        Dim recNos = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
        Dim links = {1, 1, 2, 1, 1, 2, 2, 2, 1, 2}
        Dim lineNos = {4, 6, 3, 5, 6, 7, 3, 2, 3, 4}
    
        ' transfer the arrays to a List
        Dim xs As New List(Of Grouped)
        xs.Capacity = recNos.Length
    
        For i = 0 To recNos.Length() - 1
            xs.Add(New Grouped With {.RecNo = recNos(i), .Link = links(i), .LineNo = lineNos(i)})
        Next
    
        ' sort the data
        Dim ys = xs.OrderBy(Function(x) x.Link).ThenBy(Function(x) x.LineNo).ToList()
    
        Console.WriteLine(String.Join(", ", ys))
    
        ' Now try with twenty million records
        Dim rand = New Random()
        Dim nRecs As Integer = 20000000
        recNos = Enumerable.Range(0, nRecs - 1).ToArray()
        ReDim links(nRecs - 1)
        ReDim lineNos(nRecs - 1)
    
        For i = 0 To nRecs - 1
            links(i) = rand.Next(0, 9)
            lineNos(i) = rand.Next(1, 9)
        Next
    
        Dim sw As New Stopwatch
        sw.Start()
    
        xs.Clear()
        xs.Capacity = nRecs
    
        For i = 0 To recNos.Length() - 1
            xs.Add(New Grouped With {.RecNo = recNos(i), .Link = links(i), .LineNo = lineNos(i)})
        Next
    
        sw.Stop()
        Console.WriteLine(sw.ElapsedMilliseconds.ToString())
        sw.Restart()
    
        ys = xs.OrderBy(Function(x) x.Link).ThenBy(Function(x) x.LineNo).ToList()
    
        sw.Stop()
        Console.WriteLine(sw.ElapsedMilliseconds.ToString())
    
        Console.ReadLine()
    
    End Sub
    
    End Module
    

    【讨论】:

    • 谢谢,这真的很有帮助。如果有帮助,我在时间上比空间上更注重效率(内存不是什么大问题)。理想情况下,我希望能够在不到一秒的时间内进行排序(array.sort(a1,a2) 可以在大约 1300 毫秒内对 20m 条记录进行排序)。
    猜你喜欢
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 2021-08-19
    • 2016-12-28
    相关资源
    最近更新 更多