【问题标题】:powershell sorting really large collection of objectspowershell 对非常大的对象集合进行排序
【发布时间】:2015-02-27 16:21:50
【问题描述】:

我正在尝试从大量对象 (-gt 250k) 中生成直方图。我需要根据每个对象的属性对集合进行排序。我的脚本行如下所示:

$ch = $ch | sort TotalCount -descending  <br>

$ch[x].totalcount 是一个整数。

该脚本有效,但排序需要一个多小时并消耗 6GB 内存。如何加快流程?

我已经搜索了一些解决方案,并且一些网站建议使用 [array]::sort,因为它更快。由于这是一组对象,我不确定如何使用静态 System.Array 排序方法。即使可以,我也不知道如何使数组降序(尽管反转结果应该很简单)。

关于如何使用 powershell 对非常大的集合进行排序有什么建议吗?

【问题讨论】:

    标签: sorting powershell collections


    【解决方案1】:

    让我们创建一个包含 2500 个元素的数组。数组的每个元素都是一个包含属性totalCount 的对象,我们为其分配一个整数。

    $array = @()
    1..2500 | % {
        $array += New-Object pscustomobject -Property @{
            totalCount = $_;
        }
    }
    

    现在让我们对这个数组进行排序并测量执行命令的总时间。

    我们从经典的Sort-Object 开始,使用-descending 参数:

    (Measure-Command {
        $array = $array | Sort-Object TotalCount -descending
    }).TotalSeconds  
    

    以秒为单位的总时间为:0.1217965

    现在让我们使用 System.Array 类的 Reverse 方法:[Array]::Reverse()

    (Measure-Command {
        [Array]::Reverse([array]$array)
    }).TotalSeconds  
    

    以秒为单位的总时间为:0.0002594

    差别很大!

    现在让我们看看其他可能性,让我们创建一个System.Collections.ArrayList

    $array = New-Object System.Collections.ArrayList
    1..2500 | % {
        $o = New-Object pscustomobject -Property @{
            totalCount = $_;
        }
        [Void] $array.Add($o)
    }
    

    然后我们重复一遍。我们首先使用 System.Collections.ArrayList 类的 Reverse 方法,然后将集合传递给 System.Array 的 Reverse 方法。

    (Measure-Command {
        $array.reverse()
    }).TotalSeconds
    

    以秒为单位的总时间为:0.0002459

    略有改进,但总体上非常相似。

    现在我们对系统集合进行类型转换并使用[Array]::Reverse()

    (Measure-Command {
        [Array]::Reverse([array]$array)
    }).TotalSeconds
    

    以秒为单位的总时间为:0.0008172 超过两倍的时间。这清楚地表明这不是一个好主意,所以我们放弃了它。

    结论:

    带有[Array]::Reverse() 的 System.Array 肯定比 Sort-Object 快,但是请记住 System.Array 是不可变的,所以如果构建数组是性能问题的一部分,我绝对推荐使用 @987654335 @ 因为它是可变的。

    【讨论】:

      【解决方案2】:

      [array]::reverse() 不会以任何方式对数组进行排序。

      【讨论】:

      • 如果你想让它快速排序,那么这样做:measure-command { $array = New-Object System.Collections.ArrayList 1..2500 | % { [Void] $array.Add([tuple]::create([int]$_)) } $array.sort() }
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多