2014-12-31 4 views
2

Я пытаюсь сгенерировать гистограммы из очень большой коллекции объектов (-gt 250k). Мне нужно отсортировать коллекцию по свойству каждого объекта. Моя строка скрипта выглядит следующим образом:powershell сортировка действительно большая коллекция объектов

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

где $ch[x].totalcount бы некоторое целое число.

Сценарий работает, но требуется больше часа, чтобы сортировать и потреблять 6 ГБ памяти. Как ускорить процесс?

Я искал решение, и несколько веб-сайтов предлагают использовать [array] :: sort, поскольку он намного быстрее. Поскольку это набор объектов, я не уверен, как использовать статический метод сортировки System.Array. Даже если бы я мог, я не вижу, как заставить массив спускаться (хотя реверсирование результата должно быть довольно простым).

Любые предложения по сортировке действительно больших коллекций с помощью powershell?

ответ

0

Давайте создадим массив с 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

Давайте теперь использовать метод Reverse классовой System.Array: [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) 
} 

И мы Rince и повторить. Сначала мы используем метод Reverse класса System.Collections.ArrayList, затем мы передаем коллекцию методу Обратный метод System.Array.

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

Общее время в секундах: 0,0002459

Незначительное улучшение, но очень похожи в целом.

Теперь мы типаж коллекции системы и использовать [Array]::Reverse()

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

Общее время в секундах: 0,0008172 За два раза больше времени. Это наглядно показывает, что это не очень хорошая идея, поэтому мы отказываемся от нее.

Вывод:

A Система.Массив с [Array]::Reverse() определенно быстрее, чем Sort-Object, однако имейте в виду, что System.Array неизменен, поэтому, если создание массива является частью проблемы с производительностью, я определенно рекомендую использовать System.Collections.ArrayList, поскольку он изменен.