PowerShell脚本性能优化技巧总结

最终优化

在你写脚本时,不要老是想着去优化,因为你的部分优化代码可能最终被丢弃。而且老是想着优化也会降低你的生产效率,因为和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 }

这段代码执行起来非常快,因为它避免了管道边界。但是它在处理之前会把所有文件对象加入到集合中。所以如果这个集合非常庞大,它可能会像某国的某能源局领导占用上亿人民币一样,洪水禽兽般占用系统资源。

Foreach循环比ForEach-Object,执行速度快,消耗的内存多。但是如果你能确定你要处理的数据规模不是很大,Foreach循环当然是上上之选。

使用Sleep降低CPU的使用率

接触很多对象的PowerShell脚本,通常会执行很长时间,对于处理器也不会怜香惜玉。现在单核CPU已成往事,在多核的今天这可能不是个事,但这仍旧可能会导致系统花费了大量时间去等待。如果你的脚本消耗了很多CPU周期,或者需要等待事情发生,你可以使用Start-Sleep这条命令来降低处理器的使用率。默认Slee是按秒来等待的,这肯定受不了,你可以设置一个毫秒级别的暂停。始终的分辨率不超过10到20毫秒会更好(再小就没有意义了),所以你可以指定最小暂停时间为20毫秒。

另外你可能不想让你的脚本每个循环周期中都Sleep,只让部分周期Sleep,以给CPU腾出时间去做其它事。下面的脚本会借助操作符%取模来保证每10轮暂停一次:


代码如下:

$i=0
Get-ChildItem -Recurse |
 ForEach-Object{    $i+=1
    if($i%10 –eq 0)
   {sleep -mill 20}
   do-something
}

简单的优化方案

你可以把这些小技巧归纳成一个统一的优化方案。首先,别急着优化直到脚本写完了。接着,使用Filter过滤来减少限制返回对象的数目,然后再用-include和,-exclude进行微调,这样做既会减少运行时间,也会降低资源的使用率。基于这一点,如果你的数据量比较大,就使用Foreach循环来代替Foreach-Object,这样会让你的脚本执行效率提高。当然如果你的数据规模到了10万级以上,这可能会引入新的性能问题。最后,如果你发现自己的脚本CPU占用率老高老高,看看能否在一些循环中使用Start-Sleep命令,来放松一下。

(0)

相关推荐

  • Powershell使用WPF技术实现弹窗提示实例

    WPF (Windows Presentation Foundation) 技术能让你创建窗口和对话框.它的优势是在窗体设计时能与代码分开. 这里有个简单的显示弹出消息练习.这个消息是定义在XAML代码中它的实现类似HTML(但是请区分大小写).你能轻松的调整字体大小,内容,颜色等等.不需要嵌入任何代码. 复制代码 代码如下: $xaml = @"<Window xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation

  • Powershell从注册表中查询默认MAPI客户端的例子

    当你通过类似Mailto:链接发送邮件,此时邮件客户端就是MAPI客户端.如果要找出到这个MAPI客户端在哪里,这里有个函数能从注册表中获得该信息. 复制代码 代码如下: functionGet-MAPIClient{    functionRemove-Argument    {      param      (        $CommandLine      ) $divider=''if ($CommandLine.StartsWith('"'))      {        $div

  • PowerShell注册表操作命令总结

    你可以像导航文件系统那样来访问注册表,PowerShell把文件系统和注册表都当作层次信息系统来处理.注册表中的键对应于文件系统的目录,但是键对应的值和文件系统中的文件不是非常类似.相反的,它们显示在属性栏,被以键的属性来管理. 复制代码 代码如下: PS C:\> Cd HKCU:PS HKCU:\> dir Hive: HKEY_CURRENT_USER Name                           Property----                         

  • Powershell中调用邮件客户端发送邮件的例子

    你可以使用Send-MailMessage发送邮件,但是你想从你默认MAPI客户端准备发送一份邮件,这也不是很麻烦: 复制代码 代码如下: $subject = 'Sending via MAPI client'$body = 'My Message'$to = 'tobias@powertheshell.com' $mail = "mailto:$to&subject=$subject&body=$body" Start-Process -FilePath $mail

  • PowerShell中运行CMD命令的技巧总结(解决名称冲突和特殊字符等问题)

    引言 我从老旧的 CMD.EXE 命令行换到优秀的 POWSERSHELL.EXE 已经有一段时间啦.您可能知道新的 Windows PowerShell 可以运行任何旧命令.不过有些旧命令的名称或语法可能会产生问题.但这都不是事儿. 麻烦 1:名称冲突 PowerShell 的 cmdlet 别名和旧命令的名称有冲突是个常见的问题.比如说您喜欢的服务控制命令 SC.EXE.SC.EXE 非常灵活!我能理解您为什么喜欢它(不要为用 NET.EXE 管理服务找借口).如果您想查看 SMB Serv

  • PowerShell脚本性能优化技巧总结

    最终优化 在你写脚本时,不要老是想着去优化,因为你的部分优化代码可能最终被丢弃.而且老是想着优化也会降低你的生产效率,因为和CPU的时间相比,脚本编写者的时间可能会更宝贵. 使用过滤参数 PowerShell可能会消耗很多资源,因为许多Cmdlet本身的设计就是用来提供数目很大的数据.所以,如果你使用的Cmdlet命令支持-Filter, -Include, 和 -Exclude这样的过滤条件,就尽量使用它们. 首先如果一条命令支持-Filter 过滤器参数,那就说明这里可能隐藏着一个对象访问A

  • Python 代码性能优化技巧分享

    如何进行 Python 性能优化,是本文探讨的主要问题.本文会涉及常见的代码优化方法,性能优化工具的使用以及如何诊断代码的性能瓶颈等内容,希望可以给 Python 开发人员一定的参考. Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化.扩展以及文档相关的事情通常需要消耗 80% 的工作量.优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率. 改进算法,选择合适的数据结构 一个

  • 值得收藏的20个Linux服务器性能优化技巧

    Linux是一种开源操作系统,它支持各种硬件平台,Linux服务器全球知名,它和Windows之间最主要的差异在于,Linux服务器默认情况下一般不提供GUI(图形用户界面),而是命令行界面,它的主要目的是高效处理非交互式进程,响应时间并不是那么重要,相反,能够长时间处理高负载才是最关键的.Linux高可用服务器集群解决方案让IT系统管理员可以从容应对许多常见的硬件和软件故障,允许多台计算机一起工作,为关键服务正常运行提供保障,系统管理员可以不中断服务执行维护和升级. Linux服务器有各种用途

  • 基于JavaScript 性能优化技巧心得(分享)

    JavaScript 作为当前最为常见的直译式脚本语言,已经广泛应用于 Web 应用开发中.为了提高Web应用的性能,从 JavaScript 的性能优化方向入手,会是一个很好的选择. 本文从加载.上下文.解析.编译.执行和捆绑等多个方面来讲解 JavaScript 的性能优化技巧,以便让更多的前端开发人员掌握这方面知识. 什么是高性能的 JavaScript 代码? 尽管目前没有高性能代码的绝对定义,但却存在一个以用户为中心的性能模型,可以用作参考:RAIL模型. 响应 如果你的应用程序能在1

  • Vue.js九个性能优化技巧(值得收藏)

    目录 Functional components Child component splitting Local variables Reuse DOM with v-show KeepAlive Deferred features Time slicing Non-reactive data Virtual scrolling 总结 参考资料 这篇文章主要参考了 Vue.js 核心成员Guillaume Chau在 19 年美国的 Vue conf 分享的主题:9 Performance se

  • vue项目中一定会用到的性能优化技巧

    目录 引言 性能优化标准 Lighthouse 通用常规优化手段 通用性能优化分析 FCP(First Contentful Paint) LCP(Largest Contentful Paint) SpeedIndex(速度指数) 排查性能瓶颈 分析包内容 利用chorme devtool 的代码覆盖率 针对vue 的特殊优化 图片懒加载 虚拟滚动 vue 中的函数式组件 利用v-show .KeepAlive 复用dom 分批渲染组件 最后 引言 提起性能优化 很多人眼前浮现的面试经验是不是

  • Python 性能优化技巧总结

    1.使用测量工具,量化性能才能改进性能,常用的timeit和memory_profiler,此外还有profile.cProfile.hotshot等,memory_profiler用了psutil,所以不能跟踪cpython的扩展: 2.用C来解决费时的处理,c是效率的代名词,也是python用来解决效率问题的主要途径,甚至有时候我都觉得python是c的完美搭档.常用的是Cython,直接把py代码c化然后又能像使用py包一样使用,其次是ctypes,效率最最高的存在,最后还有CPython

  • php导入大量数据到mysql性能优化技巧

    本文实例讲述了php导入大量数据到mysql性能优化技巧.分享给大家供大家参考.具体分析如下: 在mysql中我们结合php把一些文件导入到mysql中,这里就来分享一下我对15000条记录进行导入时分析与优化,需要的朋友可以参考一下. 之前有几篇文章,说了最近tiandi在帮朋友做一个小项目,用于统计电话号码的,每次按需求从数据库里随机生成打包的电话号码,然后不停地让人打这些电话号码推销产品(小小鄙视一下这样的行为).但是朋友要求帮忙,咱也不能不帮啊,是吧.程序两个星期前已经做好,测试完毕交工

  • LAMP服务器性能优化技巧之Linux主机优化

    目前LAMP (Linux + Apache + MySQL + PHP) 近几年来发展迅速,已经成为Web 服务器的事实标准. LAMP这个词的由来最早始于德国杂志"c't Magazine",Michael Kunze在1990年最先把这些项目组合在一起创造了LAMP的缩写字.这些组件虽然并不是开开始就设计为一起使用的,但是,这些开源软件都可以很方便的随时获得并免费获得.这就导致了这些组件经常在一起使用.在过去的几年里,这些组件的兼容性不断完善,在一起的应用情形变得非常普便.为了改

  • Java性能优化技巧汇总

    本文实例汇总了Java性能优化技巧.分享给大家供大家参考.具体分析如下: 这里参考了些书籍,网络资源整理出来,适合于大多数Java应用 在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. 1.尽量使用final修饰符. 带有final修饰符的类是不可派生的.在JAVA核心API中,有许多应用final的例子,例如java.lang.String.为String类指定final防止了使用者覆盖length()方法.另外,如

随机推荐