簡體   English   中英

優化腳本

[英]Optimizing a script

信息

我創建了一個腳本,用於分析Windows DNS服務器中的調試日志。

它執行以下操作:

  1. 使用[System.IO.File]類打開調試日志
  2. 在每行上執行正則表達式匹配
  3. 在自定義對象中將16個捕獲組分成不同的屬性
  4. 填充字典並附加到每個鍵的值以產生統計信息

步驟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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM