Вложенные интервалы в powershell (c #) / более быстрая альтернатива "где-объекту" с отсортированными списками? - PullRequest
0 голосов
/ 11 июля 2019

Я ищу способ ускорить (Windows 10) команду PowerShell "Where-Object" для отсортированного массива.
В конце массив будет содержать тысячи строк из файла журнала. Все строки в файле журнала начинаются с даты и времени и сортируются по дате / времени (= всегда добавляются новые строки).

Следующая команда будет работать, но она чрезвычайно медленная и неэффективна для отсортированного массива:

    $arrFileContent | where {($_ -ge $Start) -and ($_ -le $End)}

Вот (сильно упрощенный) пример:

    $arrFileContent = @("Bernie", "Emily", "Fred", "Jake", "Keith", "Maria", "Paul", "Richard", "Sally", "Tim", "Victor")
    $Start = "E"
    $Ende = "P"

Ожидаемый результат: «Эмили», «Фред», «Джейк», «Кит», «Мария», «Пол».
Я предполагаю, что с использованием «вложенных интервалов» это должно быть намного быстрее, например «найти первую запись, начинающуюся с« E »или выше и первую, начинающуюся с« P »или ниже, и вернуть все записи между ними.
» Я полагаю, что для этого должно быть простое решение powershell или .Net, поэтому мне не придется кодировать его самому, правильно?

Ответы [ 2 ]

0 голосов
/ 12 июля 2019

Эффективно также просто заменить следующим образом

$arr | where { <expression> }

$arr | & { process { if (<expression>) { $_ } } }

$arrFileContent | & { process { (if ($_ -ge $Start -and $_ -lt $End) { $_ } } }
0 голосов
/ 11 июля 2019

Давайте измерим все способы, упомянутые в комментариях. Давайте подражаем тысячам строк из файла журнала , используя Get-ChildItem:

$arrFileContent = (
    Get-ChildItem d:\bat\* -File -Recurse -ErrorAction SilentlyContinue
).Name | Sort-Object -Unique
$Start = "E"
$End   = "P"

$arrFileContent.Count 

('Where-Object', $(Measure-Command {
  $arrFileNarrowed = $arrFileContent | Where-Object {
    ($_ -ge $Start) -and ($_ -le $End)
    }
}).TotalMilliseconds, $arrFileNarrowed.Count) -join "`t"

('Where method', $(Measure-Command {
  $arrFileNarrowed = $arrFileContent.Where( {
    ($_ -ge $Start) -and ($_ -le $End)
    })
}).TotalMilliseconds, $arrFileNarrowed.Count) -join "`t"

('foreach + if', $(Measure-Command {
  $arrFileNarrowed = foreach ($OneName in $arrFileContent) {
        if ( ($OneName -ge $Start) -and ($OneName -le $End) ) {
            $OneName
        }
    }
}).TotalMilliseconds, $arrFileNarrowed.Count) -join "`t"

Вывод с использованием Get-ChildItem d:\bat\*:

D:\PShell\SO\56993333.ps1
2777
Where-Object  111,5433    535
Where method  56,8577 535
foreach + if  6,542   535

Вывод с использованием Get-ChildItem d:\* (намного больше names ):

D:\PShell\SO\56993333.ps1
89570
Where-Object  4056,604    34087
Where method  1636,9539   34087
foreach + if  422,8259    34087
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...