Оптимизация операции замены в нескольких файлах в powershell - PullRequest
1 голос
/ 13 июня 2019

Я написал скрипт ниже, чтобы перебрать файлы в каталоге, а затем выполнить замену на основе хеш-таблицы (которая на самом деле будет содержать 30 ключей / значений, а не 4, как показано здесь). Это очень, очень большой каталог, и файлы несколько большие, поэтому я хочу убедиться, что это максимально оптимизировано, но я не настолько опытен в powershell. Это все или мне нужно провести рефакторинг, и если да, что мне делать? Спасибо.

Get-ChildItem 'C:\temp' -Filter *.txt | 
Foreach-Object {
    $lookupTable = @{
        'a' = '1'
        'b' = '2'
        'c' = '3'
        'd' = '4'
    }
    $file = $_
    Write-Host "$file"
    (Get-Content -Path $file -Raw) | ForEach-Object {
        $line = $_
        $lookupTable.GetEnumerator() | ForEach-Object {
            if ($line -match $_.Key) {
            $line = $line -replace $_.Key, $_.Value
            }
        }
    $line
    } | Set-Content -Path $file
}

1 Ответ

2 голосов
/ 14 июня 2019

Вот несколько измеренных тестовых случаев (

  • цикл 5000 итераций вместо получения нескольких файлов
  • скалярное значение "ano, cosi bude jinak" вместо чтения каждого из них

)

$lookupTable = @{
    'a' = '1'
    'b' = '2'
    'c' = '3'
    'd' = '4'
}
'original approach ', ( Measure-Command {
    for ( $i = 0; $i -lt 5000; $i++ ) {                 # get-childitem
        $line = "ano, cosi bude jinak"                  # get-content
        $lookupTable.GetEnumerator() | ForEach-Object {
            if ($line -match $_.Key) {
                $line = $line -replace $_.Key, $_.Value
            }
        }
        $line
    }
}).TotalSeconds, $line -join "   "

'@mhu: without IF  ', ( Measure-Command {
    for ( $i = 0; $i -lt 5000; $i++ ) {
        $line = "ano, cosi bude jinak"
        $lookupTable.GetEnumerator() | ForEach-Object {
            $line = $line -replace $_.Key, $_.Value
        }
        $line
    }
}).TotalSeconds, $line  -join "   "

'HashTable -> Array', ( Measure-Command {
    $lookupArrayCount = $lookupTable.Count
    $lookupArray = New-Object 'array[]' $lookupArrayCount
    $j = 0
    $lookupTable.GetEnumerator() | ForEach-Object {
        $lookupArray[$j] = @( $_.Key, $_.Value )
        $j++
    }
    for ( $i = 0; $i -lt 5000; $i++ ) {
        $line = "ano, cosi bude jinak"
        for ( $j = 0; $j -lt $lookupArrayCount; $j++ ) {
            $line = $line -replace $lookupArray[$j]
        }
        $line
    }
}).TotalSeconds, $line -join "   "

выход

D:\PShell\SO\56587351.ps1
original approach    1,8059152   1no, 3osi 2u4e jin1k
@mhu: without IF     1,5973162   1no, 3osi 2u4e jin1k
HashTable -> Array   0,3225432   1no, 3osi 2u4e jin1k
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...