首页 > 开发 > PowerShell > 正文

PowerShell脚本性能优化技巧总结

2020-05-30 20:11:07
字体:
来源:转载
供稿:网友

最终优化

在你写脚本时,不要老是想着去优化,因为你的部分优化代码可能最终被丢弃。而且老是想着优化也会降低你的生产效率,因为和CPU的时间相比,脚本编写者的时间可能会更宝贵。

使用过滤参数

PowerShell可能会消耗很多资源,因为许多Cmdlet本身的设计就是用来提供数目很大的数据。所以,如果你使用的Cmdlet命令支持-Filter, -Include, 和 -Exclude这样的过滤条件,就尽量使用它们。

首先如果一条命令支持-Filter 过滤器参数,那就说明这里可能隐藏着一个对象访问API。使用过滤,可能会让代码执行得非常快,因为通常会在对象被创建之前就执行过滤。相反一条命令支持-Include, 和 -Exclude,这样的过滤会发生在对象被创建后,对象进入管道之前。所以后者的效率比-Filter 要低。尽管如此,使用-Include, 和 -Exclude后,让部分对象不进入管道,速度也是非常快的。

有时,应当使用更多的类型去过滤。比如你想搜索D盘下所有的后缀名为htm的文件。我们应当会使用*.htm作为过滤-Filter条件,PowerShell使用传统的文件系统通配符,仅会返回所有匹配到的文件对象。这样效率很高,因为这种简单模式匹配,Windows API本身在底层就实现了。然而Windows API本身也有许多限制,因为它太老了,它会忽略文件后缀名中除了htm这三个字符以外的所有字符。所以即使有Html这样后缀名它也会返回。所以此时,我们需要-filter和-include双剑合璧,打败金轮法王。
代码如下:dir D: -Filter '*.htm' -Include '*.html' -Recurse
但是有一点要记住,使用-Filter过滤条件是很快,但是到底快到什么程度取决于-Filter调用的底层API。我们来举个例子吧:
代码如下:Get-WmiObject -Class Win32_Product  -Filter 'Vendor LIKE "%Microsoft%"'
这个例子会查询机器安装的所有微软的产品,纵然我们使用了-filter,仍旧很慢?因为-Filter调用的是Windows Management Instrumentation (WMI)API,这个是基于WMI查询语言(WQL)的,过滤是发生在WMI内部的。

减少资源的占用

性能的优化包括降低时间复杂度和空间复杂度,但是很多时候,鱼和熊掌不可兼得。你只能选择其一。举个例子吧:比如你想列出D盘下所有的文件,然后针对每个文件做点事情,你可能会使用ForEach-object来变量整个集合中的文件系统对象:
代码如下:Get-ChildItem -Path D:/ -Recurse | ForEach-Object { do-something }
使用了这个命令后,每一个文件对象经过额外的包装后,会经过管道的边界,代码的执行效率显著下降,但是它不会占用太多内存,因为每次只有一个对象在管道中流通。

另外一种方法,你可能会使用Foreach循环:

代码如下:foreach($file in (Get-ChildItem -Path D:/ -Recurse)){
 do-something }

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表