function - 如何更有效地编写此Powershell函数?

标签 function powershell cpu-usage

我以多种不同的方式介绍了有关高效Powershell脚本的许多网站
但是我仍然可以使用帮助来提高此脚本的效率...它使用3-4%的CPU。处理器上的主要阻力是MainLogic功能。它嵌套在脚本主体开头的While($ true)循环中,并始终运行...当MainLogic函数中的某些参数更改时,函数中断,并且确定if语句是否在主体中进行了测试剧本。我正在尝试学习如何编写更高效的代码...我正在练习成为Lisp开发人员,我认为关于Powershell效率的一课对我们所有人都是有益的。我已经将该脚本重写了3次,但是我仍然需要帮助使其变得更好...我看到大多数Windows进程几乎不使用CPU,并且它们一直运行并且是非常聪明的代码。我想成为那么好。我需要脚本中的所有内容\我必须测试他在脚本中测试的所有内容。我评论说很多可以帮助某人帮助我

香港专业教育学院尝试了这些事情:

  • 我是否针对这种情况使用了正确的构造?我采用了多种方法……我想是的,但是可能会有更好的数学方法……我正在学习线性代数来帮助我。
  • 我执行太多或不必要的操作吗?这是我的主要问题。...可以在新思路中使用帮助
  • 我处理的对象太多吗?不知道是否还有另一种方法....我认为我使用了最小限度的对象,但是Getwmiobject是否比Get-Process好?等
  • 管道是最好的方法吗?我想我的管道很好
  • 是否有另一个可能更好用的命令模型?我用谷歌搜索,但找不到与Powershell
  • 有关的命令模型
  • 我是否在适当考虑对象?虽然在Google上似乎找不到很好的PowerShell对象类(class),但我已经阅读了1 1 \ 2 Powershell书籍,但是在它们中没有相似的代码
  • 我是否在使用-Filter(如果可用)?不适用于Get-Process
  • 我是否不必要地重新初始化变量?没有重新初始化
  • 我的循环设计有效吗?我认为我是设计它们的最佳方法-一会儿($ true)嵌套在另一会儿while($ true)内,所以我不会在每个循环中都运行整个脚本...。我需要MainLogic函数中的所有内容(我的循环一直运行)
  • 我在何时使用Foreach-Object也能正常工作吗?不适用
  • 我是否一次检索值,并在以后需要时再次保存在变量中?...我这样做
  • 您是否将大型集合传递到管道而不是存储在对象中?...不这样做
  • 我是否不必要地测试条件?是吗

  • 这仅仅是一个大脚本,还是我看不到编码方面的大局呢.... pls引用在线资源来帮助我编写更有效的代码,如果您在我的逻辑中看到“空洞”。

    这是我的脚本:MainLogic Function是Processor hog,所有需要查看的内容....我添加了其余的内容来帮助我。提前致谢
    #this function is ran by itself in a while($true) loop and is the main place in my script where information 
    about Firefox.Skype and VPN Processes is gathered.
    function global:MainLogic()
    {
    
    #Monitor Skype WorkingSet for any changes - If change is detected the change it is processed under the
    #"Skype Logic" Section to find out if a Skype call is in progress. 
    $SkypeProcess1 = get-process | where-object {$_.ProcessName -eq "skype"}
    ss -s 1
    $SkypeProcess2 = get-process | where-object {$_.ProcessName -eq "skype"}
    
    $SkypeWsDiff = $SkypeProcess2.workingset - $SkypeProcess1.workingset
    
    ###Skype Logic###
    
    #Test Skype Call Status and if changed break from this function in the ###SKype Break### sectiom below and 
    #check all parameters in body of script.
    
    $y = $x
    wo "`$x `= $x"
    wo "`$y `= $y"
    
    #Testing Information gathered in above section to see if Skype call in progress.
    
    if($SkypeWsDiff -gt 8000000){$x = 1}
    elseif($SkypeWsDiff -lt -11000000){$x = 2}
    wo "Function2 `$x `= $x"
    if ($x -eq 1){wo "Skype Telephone Call in Progress"
    }
    if ($x -eq 2){wo "Skype Telephone Call not in Progress"
    }
    wo "`$SkypeWsDiff `= $SkypeWsDiff"
    
    ###SKype Break###
    if($y -ne $x){wo "Skype changed - break"
    break}
    wo "`$x `= $x"
    wo "`$y `= $y"
    #Skype Logic End
    
    #Firefox Status gathered below and saved to variable $a is saved to variable $b here and stored to compare later 
    #with variable $a to see if Firefox Status changed.
    
    $b = $a
    wo "`$a `= $a"
    wo "`$b `= $b"
    
    
    #VPN Status gathered below and saved to variable $c is saved to variable $d here and stored to compare later 
    #with variable $c to see if VPN Status changed.
    
    $d = $c
    wo "`$c `= $c"
    wo "`$d `= $d"
    
    #Firefox and VPN status are saved here to variables for comparison later and above this section in the script.
    if(ps firefox -ea 0){$a = 3 ; wo "Firefox is Open"
    }
    if(-not(ps firefox -ea 0)){$a = 4 ; wo "Firefox is Closed"
    }
    if(ipconfig | Select-String 'PPP adapter'){$c = 5 ; wo "VPN is Connected"
    }
    if((ipconfig | Select-String 'PPP adapter') -eq $null){$c = 6 ; wo "VPN is not connected"
    }
    
    #This is where the Firefox Variable comparison mentioned above actually happens. If change is detected the script
    #breaks from this function and subsequently if\then logic is tested in body of script.
    if($b -ne $a){wo "Firefox changed - break"
    break}
    wo "`$a `= $a"
    wo "`$b `= $b"
    
    #This is where the VPN Variable comparison mentioned above actually happens. If change is detected the script
    #breaks from this function and subsequently if\then logic is tested in body of script.
    if($d -ne $c){wo "VPN changed - break"
    ss -s 2
    break}
    wo "`$c `= $c"
    wo "`$d `= $d"
    
    }
    
    #Functions
    
    
    #If Firefox is Open and VPN is Connected - Disconnect VPN
    
    if ((ps firefox -ea 0) -and (ipconfig | Select-String 'PPP adapter')) {
    rasdial "BTGuard VPN" /DISCONNECT
    ss -s 5
    }
    
    #If Firefox is not Open and VPN is not Connected - Connect VPN
    if ((-not(ps firefox -ea 0)) -and ((ipconfig | Select-String 'PPP adapter') -eq $null)) {
    rasdial "BTGuard VPN" joe 11223344
    }
    
    while($true){
    
    while($true){. MainLogic}
    #If Skype call not in progress(variable $x) and Firefox is open and VPN is not connected - do nothing
    if($x -eq 2 -and (ps firefox -ea 0) -and (ipconfig | Select-String 'PPP adapter') -eq $null)
    {
    
    }
    #ElseIf Skype call not in progress(variable $x) and Firefox is not open and VPN is connected - do nothing
    elseif($x -eq 2 -and (-not(ps firefox -ea 0)) -and (ipconfig | Select-String 'PPP adapter')){
    
    }
    #ElseIf Skype call not in progress(variable $x) and Firefox is open and VPN is connected - Disconnect VPN
    elseif($x -eq 2 -and (ps firefox -ea 0) -and (ipconfig | Select-String 'PPP adapter')){
    
    ss -s 1
    rasdial "BTGuard VPN" /DISCONNECT
     }
    #ElseIf Skype call not in progress(variable $x) and Firefox is not open and VPN is not connected - Connect to VPN
    elseif($x -eq 2 -and (-not(ps firefox -ea 0)) -and (ipconfig | Select-String 'PPP adapter') -eq $null){
    
    rasdial "BTGuard VPN" joe 11223344
    }
    #ElseIf Skype call in progress(variable $x) - Do Nothing
    elseif($x -eq 1){
    }}
    

    最佳答案

    3-4%的CPU使用率不是很多。就是说,使用Measure-Command查看哪些语句消耗时间,哪些不消耗时间。

    在一般意义上,请尝试避免不必要的工作。也就是说,某些Commandlet提供了内置过滤。为此,将输出管道传递到?是浪费的。考虑Get-Process:

    Measure-Command -Expression { get-process | ? { $_.processname -eq "iexplore" } }
    Measure-Command -Expression { get-process -name "iexplore"  }
    

    在我的系统中,第一个平均大约需要13毫秒。第二个大约需要1.5毫秒。改进大约十年。

    另外,考虑将命令结果存储到变量中,而不要一直重新运行命令。例如,代码中充斥着诸如ipconfig | Select-String之类的语句。代替这些,将输出存储到变量中并仅在必要时更新变量。

    关于function - 如何更有效地编写此Powershell函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16542959/

    相关文章:

    c++ - 为什么我的功能没有运行?

    c - 在 C 中,如何计算一个函数中的局部变量,在另一个函数中?

    c++ - 将 lambda 作为参数传递 - 通过引用或值?

    windows - 将 ScheduledJob 注册为系统帐户(无需传入凭据)

    linux - 获取 Linux 进程资源使用情况(cpu、磁盘、网络)

    javascript - 如何减少此 javascript 代码的 cpu 使用率?

    PHP:如何计算人的月龄

    exception - PowerShell不断抛出异常

    powershell - Powershell获取驱动器列表

    linux - 提高 avconv 负载和速度?