我正在编写一个Powershell脚本(PS版本4)来解析和处理IIS日志文件,我遇到了一个我不太明白的问题:写入输出似乎为脚本增加了大量的处理时间。它的核心是这个(还有更多,但这证明了这个问题):
$file = $args[0]
$linecount = 0
$start = [DateTime]::Now
$reader = [IO.File]::OpenText($file)
while ($reader.Peek() -ge 0) {
$line = $reader.ReadLine()
$linecount++
if (0 -eq ($linecount % 10000)) {
$batch = [DateTime]::Now
[Console]::Error.WriteLine(" Processed $linecount lines ($file) in $(($batch - $start).TotalMilliseconds)ms")
$start = $batch
}
$parts = $line.split(' ')
$out = "$file,$($parts[0]) $($parts[1]),$($parts[2]),$($parts[3]),$($parts[4]),$($parts[5]),$($parts[6]),$($parts[7])"
## Send the output out - comment in/out the desired output method
## Direct output - roughly 10,000 lines / 880ms
$out
## Via write-output - roughly 10,000 lines / 1500ms
write-output $out
}
$reader.Close()
调用.\script.ps1 {path_to_340,000_line_IIS_log} > bob.txt
;进度/表现时间在stderr上给出。
上面的脚本有两条输出线 - write-output
每行报告10,000行,而没有write-output
的行则是一半,平均每10,000行约880毫秒
我认为如果没有其他东西(即,我认为write-output
等同于"bob"
),对象默认为write-output "bob"
,但我正在争论的时间对此。
我在这里缺少什么?
答案 0 :(得分:1)
只是一个猜测,但是:
查看写输出的帮助
Write-Output [-InputObject] <PSObject[]> [-NoEnumerate] [<CommonParameters>]
你给它一个对象列表作为一个参数,所以它必须花一点时间在它们写入之前在内部汇编成一个数组,而简单地输出它们只是立即将它们流到管道。您可以将它们传递给Write-Object,但这会添加另一个可能更糟糕的管道。
修改强>
此外,你会发现每次操作(1500 -880)/ 10000增加0.062毫秒。您必须在非常大的数据集变得明显之前将其扩展。