[英]Optimizing a script
我創建了一個腳本,用於分析Windows DNS服務器中的調試日志。
它執行以下操作:
[System.IO.File]
類打開調試日志 步驟1和2耗時最長。 實際上,它們花費了看似無休止的時間,因為文件在讀取時會不斷增長。
由於調試日志的大小(80,000kb),因此需要很長時間。
我相信我的代碼適用於較小的文本文件,但無法處理較大的文件。
這是我的代碼: https : //github.com/cetanu/msDnsStats/blob/master/msdnsStats.ps1
這就是調試的樣子(包括空行)
乘以大約100,000,000 ,您便得到了我的調試日志。
21/03/2014 2:20:03 PM 0D0C PACKET 0000000005FCB280 UDP Rcv 202.90.34.177 3709 Q [1001 D NOERROR] A (2)up(13)massrelevance(3)com(0)
21/03/2014 2:20:03 PM 0D0C PACKET 00000000042EB8B0 UDP Rcv 67.215.83.19 097f Q [0000 NOERROR] CNAME (15)manchesterunity(3)org(2)au(0)
21/03/2014 2:20:03 PM 0D0C PACKET 0000000003131170 UDP Rcv 62.36.4.166 a504 Q [0001 D NOERROR] A (3)ekt(4)user(7)net0319(3)com(0)
21/03/2014 2:20:03 PM 0D0C PACKET 00000000089F1FD0 UDP Rcv 80.10.201.71 3e08 Q [1000 NOERROR] A (4)dns1(5)offis(3)com(2)au(0)
與現在相比,我需要一些方法或想法來更快地打開和讀取文件的每一行。
我願意接受使用其他語言的建議。
我會交易這個:
$dnslog = [System.IO.File]::Open("c:\dns.log","Open","Read","ReadWrite")
$dnslog_content = New-Object System.IO.StreamReader($dnslog)
For ($i=0;$i -lt $dnslog.length; $i++)
{
$line = $dnslog_content.readline()
if ($line -eq $null) { continue }
# REGEX MATCH EACH LINE OF LOGFILE
$pattern = $line | select-string -pattern $regex
# IGNORE EMPTY MATCH
if ($pattern -eq $null) {
continue
}
為了這:
Get-Content 'c:\dns.log' -ReadCount 1000 |
ForEach-Object {
foreach ($line in $_)
{
if ($line -match $regex)
{
#Process matches
}
}
這樣一來,文件讀取操作的數量將減少1000倍。
交易選擇字符串操作將需要重構其余代碼以使用$ matches [n]而不是$ pattern.matches [0] .groups [$ n] .value,但速度要快得多。 Select-String返回matchinfo對象,該對象包含有關匹配的許多其他信息(行號,文件名等),如果需要,這是很好的選擇。 如果您需要的只是捕獲中的字符串,那么這是浪費時間。
您正在創建一個對象($ log),然后將值累加到數組屬性中:
$log.date += @($pattern.matches[0].groups[$n].value); $n++
陣列的增加會影響您的性能。 同樣,哈希表操作比對象屬性更新快。
我首先將$ log創建為哈希表,並將鍵值創建為數組列表:
$log = @{}
$log.date = New-Object collections.arraylist
然后在循環中:
$log.date.add($matches[1]) > $nul)
填充所有數組列表后,然后從$ log創建對象。
作為一般建議,請使用Measure-Command
來找出哪些腳本塊花費的時間最長。
話雖如此,睡眠過程似乎有點不可思議。 如果我沒有記錯的話,那么每行之后您會睡20毫秒:
sleep -milliseconds 20
將日志大小乘以20 ms,進行1億次迭代,您將獲得相當長的總睡眠時間。
嘗試一些合適的批次大小后再睡覺。 嘗試如果1萬行是這樣,
if($i % 10000 -eq 0) {
write-host -nonewline "."
start-sleep -milliseconds 20
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.