Powershell 优化脚本 信息

Powershell 优化脚本 信息,powershell,Powershell,我创建了一个脚本,用于分析来自Windows DNS服务器的调试日志 它做了以下工作: 使用[System.IO.File]类打开调试日志 在每行上执行正则表达式匹配 将16个捕获组分离到自定义对象内的不同属性中 填充字典并附加到每个键的值以生成统计信息 步骤1和2耗时最长。事实上,它们花费的时间似乎无穷无尽,因为文件在读取过程中不断增长 问题 由于调试日志的大小(80000KB),需要很长时间 我相信我的代码可以处理较小的文本文件,但它无法处理更大的文件 代码 这是我的密码: 调试日志预览 这

我创建了一个脚本,用于分析来自Windows DNS服务器的调试日志

它做了以下工作:

  • 使用
    [System.IO.File]
    类打开调试日志
  • 在每行上执行正则表达式匹配
  • 将16个捕获组分离到自定义对象内的不同属性中
  • 填充字典并附加到每个键的值以生成统计信息
  • 步骤1和2耗时最长。事实上,它们花费的时间似乎无穷无尽,因为文件在读取过程中不断增长

    问题 由于调试日志的大小(80000KB),需要很长时间

    我相信我的代码可以处理较小的文本文件,但它无法处理更大的文件

    代码 这是我的密码:

    调试日志预览 <>这是调试的样子(包括空白行)

    将该值乘以大约100000000,您就有了我的调试日志

    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)
    
    要求 我需要比现在更快地打开和阅读文件的每一行的方法或想法


    我愿意接受使用不同语言的建议。

    作为一般建议,请使用
    Measure命令
    找出哪些脚本块花费的时间最长

    话虽如此,睡眠过程似乎有点怪异。如果我没有错,你每行睡20毫秒:

    睡眠-毫秒20

    将20毫秒乘以日志大小,1亿次迭代,您将获得相当长的总睡眠时间

    试着在合适的批量后睡觉。如果10000行是这样的话,试试看

    if($i % 10000 -eq 0) {
        write-host -nonewline "."
        start-sleep -milliseconds 20
    }
    
    我想交换这个:

    $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倍

    交易select string操作将需要重新分解代码的其余部分,以使用$MATCHS[n]而不是$pattern.MATCHS[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创建对象。

    Genius!我会尽快试试这个。我认为这会起作用。我将您的答案标记为正确,因为
    readcount
    建议确实加快了脚本的速度,但是它仍然远远不够快,无法处理我的行数(现在已达到5.5亿行)。我已经完全重写了代码,如果您愿意的话,我将在本周的某个时候上传到github。