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

Function 如何更有效地编写此Powershell函数?,function,powershell,cpu-usage,Function,Powershell,Cpu Usage,我从很多不同的角度来看了这一点,并在很多网站上看到了高效的Powershell脚本 但我仍然需要帮助使这个脚本更高效…它使用了3-4%的CPU。处理器上的主要阻力是MainLogic函数。它嵌套在脚本正文开头的While$true循环中,并一直运行……当MainLogic函数中的某些参数更改时,函数中断,并且脚本正文中的某些if-then语句被测试。我正在努力学习如何编写更高效的代码……我正在练习成为一名Lisp开发人员,我认为上一堂关于Powershell效率的好课对我们大家都有好处。我已经重

我从很多不同的角度来看了这一点,并在很多网站上看到了高效的Powershell脚本 但我仍然需要帮助使这个脚本更高效…它使用了3-4%的CPU。处理器上的主要阻力是MainLogic函数。它嵌套在脚本正文开头的While$true循环中,并一直运行……当MainLogic函数中的某些参数更改时,函数中断,并且脚本正文中的某些if-then语句被测试。我正在努力学习如何编写更高效的代码……我正在练习成为一名Lisp开发人员,我认为上一堂关于Powershell效率的好课对我们大家都有好处。我已经重写了3次这个脚本,我仍然需要帮助使它更好…我看到大多数windows进程几乎不使用CPU,它们一直在运行,并且是非常智能的代码。我很想做得那么好。我需要脚本中的所有内容\我必须测试脚本中测试的所有内容。我说了很多话来帮助别人帮助我

我试过这些东西:

对于这种情况,我是否使用了正确的结构?我在这方面有很多经验…我想我是的,但可能有更好的数学方法…我正在学习线性代数来帮助我解决这个问题。 我是否做了太多或不必要的操作?这是我的主要问题……我需要新想法的帮助 我使用的对象太多了吗?不确定是否还有其他方法……我想我使用了最小的项目,但是GetWMIOObject比Get流程好吗?等 管道是最好的方法吗?我想我的管道很好 是否有另一种命令模式可以更好地工作?我在谷歌上搜索过,但找不到与Powershell相关的命令模型 我是否正确地思考对象?在Google上似乎找不到一个好的PowerShell对象课程,但我已经读了11\2本PowerShell书籍,但其中没有类似的代码 我是否在使用-过滤器(如果可用)?不可用于Get进程 我是否不必要地重新初始化变量?没有重新初始化 我的循环设计有效吗?我认为我设计它们的方式是最好的——一个while$true嵌套在另一个while$true中,这样我就不会在每个循环中运行整个脚本……我需要MainLogic函数中的所有东西我的循环一直在运行 我是否在使用Foreach对象,for何时也能正常工作?不适用 我是否要检索一次值,并在以后需要时保存在变量中?…我会这样做 是否将大型集合传递到管道而不是存储在对象中?…不这样做 我是否测试了不必要的条件?是吗? 这只是一个大脚本,还是我没有看到编码方面的大局……如果你看到我的逻辑中有漏洞,请引用在线资源帮助我编写更高效的代码

这是我的脚本:MainLogic函数是处理器猪和所有需要查看的东西……我添加了其余的来帮助我的帮助。提前谢谢

#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命令查看哪些语句消耗时间,哪些语句不消耗时间

一般来说,尽量避免不必要的工作。也就是说,一些commandlet提供内置过滤。对于这种情况,管道输出到?这是浪费。考虑获取过程:

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


此外,考虑将命令结果存储到变量中,而不是一直重新运行命令。例如,代码中充斥着像ipconfig | Select String这样的语句。相反,将输出存储到变量中,并仅在必要时更新变量。

3-4%的CPU使用率并没有那么高。也就是说,使用Measure命令查看哪些语句消耗时间,哪些语句不消耗时间

一般来说,尽量避免不必要的工作。也就是说,一些commandlet提供内置过滤。对于这种情况,管道输出到?这是浪费。考虑获取过程:

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


此外,考虑将命令结果存储到变量中,而不是一直重新运行命令。例如,代码中充斥着像ipconfig | Select String这样的语句。相反,将输出存储到变量中,并仅在必要时更新变量。

+1,并且第一段至少需要+10。3%的CPU很小,即使是30%也不值得担心,除非CPU非常有限。从本质上讲,网络或磁盘IO可能是限制因素。@vonPryz我知道3-4%很小,但我看到持续运行的windows进程都保持在0%左右,我很想在P-Shell中编写这样的脚本……感谢您的输入并很快回复我,我会尽快尝试这些事情……我的问题是否按照网站规则正确组织,而Richard并不真正理解你的评论——会吗
请你为我详细说明。+1,第一段至少需要+10。3%的CPU很小,即使是30%也不值得担心,除非CPU非常有限。从本质上讲,网络或磁盘IO可能是限制因素。@vonPryz我知道3-4%很小,但我看到持续运行的windows进程都保持在0%左右,我很想在P-Shell中编写这样的脚本……感谢您的输入并很快回复我,我会尽快尝试这些事情……我的问题是否按照网站规则正确组织,而Richard并不真正理解你的评论——请你为我详细说明一下。
Measure-Command -Expression { get-process | ? { $_.processname -eq "iexplore" } }
Measure-Command -Expression { get-process -name "iexplore"  }