设为首页 收藏本站
查看: 1226|回复: 0

38. PowerShell- 性能优化,多线程,提速

[复制链接]

尚未签到

发表于 2018-9-2 11:56:37 | 显示全部楼层 |阅读模式

  •   PowerShell优化和性能测试
  概述
  PowerShell已经存在很长一段时间了,许多基本的问题都得到了很好的解决。对于脚本编写者来说,借助于PowerShell的Get-Help帮助文档,互联网,和社区资源,绝大多数普通的任务应当用什么,怎么样来完成,都应该能快速找到答案。一旦脚本写好了,没有bug,准备投入到生产环境中了,可能另外一些问题会浮出水面,正好也是我们平时讨论的比较少的。怎么尽可能的写出更好的脚本?将已经正在使用的脚本改进的更加高效,强化工具。而这些正好需要一些不同的问题和思想来处理。这样就会开始把脚本编写者从最终用户和管理员的世界中解放出来,进入开发者的领域。虽然有些人很不情愿捡起另外一顶帽子,混入开发圈。但是真的没有比PowerShell更好的工具为你在平行宇宙中打开另一扇门。因此,让我们来看一眼一些最大化提高脚本性能的基本概念,然后转到一些深刻的问题上,看看我们离挑战极限还有多大的差距。
  PowerShell 有两个关键领域没有引起它们应得的关注,那就是优化和性能测试。所谓优化,就意味着脚本的设计和修改要尽可能减少在运行过程中时间和资源的占用。简而言之,就是要改造代码,让它快速和高效地运行。性能测试总是与优化并驾齐驱,通过脚本执行的结果,来决定优化是否有效。这种方式真的可以搞清楚所谓的“改造”,是不是真的改好了。同时还有一种优化无需性能测试即可避免很多问题。这里引用一下,我曾多次看到关于无测试优化的一句话:
  优秀的工程源于可预知的成本创造可预知的结果。我想说的是没有测量就没有工程。
  引用自:“Web应用程序性能测试指南”。
  “没有测量就没有工程”确实, 这是一篇旧文章,但是它的观点放在现在依然像它刚发表时一样有意义。唯一的途径就是真诚地验证你所有的返工是否能从现实世界的结果中得到好处。而,性能测试是完成它的关键方式。
  最佳执行的默认顺序
  根据刚才拟定的条款,让我们讨论一些应当提前了解的PowerShell的基础知识点。更好地认识PowerShell是前提。如果连基本的知识都不了解,探讨高级的概念价值也不大。比如,Bruce Payette列出最佳执行顺序的提纲,它是基于你正在运行的是那一类命令。在2.1.2章节(命令分类中),从30页到34页,他说按照执行速度的快慢,命令的类型顺序如下:
  Cmdlets:编译过的二进制文件
  函数:驻留在内存中的脚本代码
  脚本(脚本命令):保存在ps1 文件中的函数或命令
  原生的Win32可执行文件:传统的可执行文件
  因此,如果你有一个Win32可执行文件,可能把它移植进一个脚本,一个函数,甚至一个cmdlet可能会带来速度的提升。这可能并不是永远都可行,但是,有很多场景把你的功能移植到上游可以对你的PowerShell代码的执行效率带来改善。这里的关键点是理解怎样使用不同种类的命令可能会影响你的脚本最终优化的程度。
  优化注意事项
  通过执行优化的基本顺序,我们可以通过提出一些问题,然后根据这些问题来开始完善你的脚本。
  执行优化时,下面的这些问题会被经常问到:
  ·         这种情况下我是否使用了正确的构造函数?
  ·         我是否做了很多不需要的操作?
  ·         我是否使用了太多的对象?
  ·         我是否使用了很多共享资源?
  ·         我使用的集合合适吗?换个问法:我是否使用了正确或者最好的集合来完成这个任务?
  ·         管道是最好的途径吗?
  ·         是否有另外的命令模型可能会更好?
  ·         我对于对象的思考是否合适?
  ·         我有没有使用-filter(如果有)?
  ·         我预定义的变量是不是没有用到?
  ·         对于一些任务,使用Job和Runspaces是不是有用?
  ·         我的循环是否设计的高效?
  ·         我使用的ForEach-Object,如若使用For会不会更好?
  ·         当你的脚本中有 ForEach-Object时,你有没有用到begin-process-end结构?
  ·         你有没有使用高级的函数?
  ·         你有没有做参数检查?
  ·         你有没有使用严格模式(Strict-Mode)?
  ·         当我远程连接时,比如活动目录,我又没有限制返回对象的数量?
  ·         当我从网路中获取数据时,我又没有使用filter,where和其它参数指定返回值,以限制返回的结果的数量?
  ·         我有没有第一次拿到数据时,把它保存到变量中,以便于下次用到?
  ·         是不是有一个低层次的方案更高效?比如.NET?P/Invoke?
  ·         你是不是使用管道传递集合而不是使用一个大集合存储?
  ·         你是不是测试了一个没必要的条件判断?
  下面来演示为什么上述提问可能会造成问题:
  我使用了-filter吗(如果有)?
  下面的脚本片段演示怎样使用适当的命令的-Filter参数来较强地提升效率。例如我使用Get-ChildItem -Filter和Get-ChildItem | Where {$_.Name -eq ‘100Mb.txt’搜索一个文件“C:\test\100Mb.txt”。
  Clear-Host
  1..10 |
  ForEach-Object {
  "Command: output $_"
  "-" * 25
  $test1 = { Get-ChildItem -Path C:\test -Filter 100mb.txt | Out-Null }
  $test2 = { Get-ChildItem -Path C:\test | Where {$_.Name -eq '100Mb.txt'} | Out-Null }
  $results1 = (Measure-Command -Expression $test1).Ticks
  $results2 =(Measure-Command -Expression $test2).Ticks
  "{0}`t`t{1}" -f '-filter',$results1
  "{0}`t`t`t{1}" -f 'Where',$results2
  ""
  "{0}`t`t{1:N}" -f 'Difference',($results1/$results2)
  ""
  }
  测试证明,在这个很小的案例中,使用-Filter参数比备受青睐的ForEach-Object中使用Where,速度可以提升4-8倍。我们通常情况下,喜欢用foreach,但是简单的过滤器过滤,可以非常有意义的提升脚本速度。
  我使用的ForEach-Object,如若使用For会不会更好?
  下面的脚本片段我们使用ForEach-Object来替换for循环进行测试:
  "Command: output 1"
  "-" * 25
  $test1 = { 1..1000 | % { 1 } }
  $test2 = { for($i = 1; $i -le 1000; $i++) { 1 }}
  $results1 = (Measure-Command -Expression $test1).Ticks
  $results2 =(Measure-Command -Expression $test2).Ticks
  "{0}`t`t{1}" -f 'foreach',$results1
  "{0}`t`t`t{1}" -f 'for',$results2
  ""
  "{0}`t`t{1:N}" -f 'Difference',($results1/$results2)
  ""
  "Command: evaluate 1 -eq 1"
  "-" * 25
  $test3 = { 1..1000 | % { 1 -eq 1 } }
  $test4 = { for($i = 1; $i -le 1000; $i++) { 1 -eq 1 }}
  $results3 = (Measure-Command -Expression $test3).Ticks
  $results4 =(Measure-Command -Expression $test4).Ticks
  "{0}`t`t{1}" -f 'foreach',$results3
  "{0}`t`t`t{1}" -f 'for',$results4
  ""
  "{0}`t`t{1:N}" -f 'Difference',($results3/$results4)
  这段代码在我的机器上执行后,结果如下:
  Command: output 1
  -------------------------
  foreach 903091
  for 18212
  Difference 49.59
  Command: evaluate 1 -eq 1
  -------------------------
  foreach 907313
  for 22254
  Difference 40.77
  测试表明ForEach-Object在我的机器上比直接使用For循环要慢40-50倍。因为ForEach对集合进行迭代和控制,是需要时间的。所以这也是一点,全面优化脚本时需要考虑的。
  我是不是测试了一个没必要的条件判断?
  很多时候,我们用来判断条件是真或者假时,有一些更简单的实际上无须评估的方式。比如像这样判断一个变量是不是true?
  if(1 -eq $true)
  {
  Do-Something
  }
  你可以非常简单地把判断直接交给If就够了。
  if(1)
  {
  Do-Something
  }
  为了测试上面的区别,我简单写了一段脚本,发现跳过If中的判断,可以换取大概5%的性能。
  $test_001 = { if(1 -eq $true) {1} else {0}}
  $test_002 = { if(1) {1} else {0}}
  Get-ChildItem variable:\test_* |
  ForEach-Object {
  Measure-Command -Expression {1..100000 | % { $_ }} |
  select TotalSeconds
  }
  运行后的结果:
  TotalSeconds
  ------------
  12.1220562
  11.732413
  例子虽小,但是可以说明如果一个布尔类型的判断在IF语句中,是可以直接省略判断,反而能提升性能。
  性能测试注意事项
  性能测试有很多需要注意的地方,下面会列出来一些关键点,用来审查你的命令和脚本。
  ·         你是否测试过足够多的迭代次数和变化,来取平均结果?
  ·         你的测试会随着数据,结构系统波动吗?
  ·         测试的结果能否重现?
  ·         你能解释为什么你的测试能验证你的改动和优化?
  ·         如果第一次迭代比后续的迭代速度要快,可能是结果被缓存了。果真这样,可以在迭代之间插入一个停顿,刷新缓存,然后得到一致的结果。

  •   让你的PowerShell For循环提速四倍
  •   优化PowerShell的性能和内存消耗
  •   PowerShell提速和多线程
  •   优化PowerShell脚本的几个小技巧
  •   轻量级的PowerShell性能测试

  参考:
  http://www.pstips.net/optimization-and-performance-testing.html


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-561532-1-1.html 上篇帖子: powershell 带参数创建共享 下篇帖子: PowerShell快速查看和绑定DHCP用户
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表