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) "" }
"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
if(1 -eq $true) { Do-Something }
if(1) { Do-Something }
$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
Will Steele edited Revision 10. Comment: Added new link to resources
Will Steele edited Revision 11. Comment: Added link to Resources
Will Steele edited Revision 12. Comment: Add Doug Finke link
Al Dunbar edited Revision 13. Comment: removed the implicit assumption that one's powershell code resides only in powershell scripts.
Richard Mueller edited Revision 14. Comment: Added toc
FZB edited Revision 15. Comment: typo
Josh Miller 76 edited Revision 17. Comment: Test Considerations expand bullet 1
Richard Mueller edited Revision 18. Comment: Added testing consideration to avoid distortions due to caching
Josh Miller 76 edited Revision 19. Comment: Adding a link to PowerShell Team blog about ways to suppress output.
Will Steele edited Revision 20. Comment: Added section: Am I testing a condition unnecessarily?
Alex Angelopolous nailed it when he wrote: "Don't try to optimize PowerShell scripts as you write them. You might be optimizing code that either disappears on its own or doesn't have a significant effect on final performance. Scripter time is always more difficult to come by than CPU cycles."
I would extend this to suggest that care be taken to code in the most general manner possible by such strategies as: naming variables for what they actually mean, avoiding the re-use of variables for purposes other than their initial use, and avoiding complex expressions, among others.
Collections can be processed in a variety of ways, given the set of available looping and conditional structures. The choice may have performance implications, but it also has ease of understanding implications. Saving current run-time at the expense of making future maintenance more difficult is, in my mind, a questionable tactic. As well, it can often be the case that improved speed comes at the expense of other resources, such as memory.
There is another old saw that applies here: optimize only in those cases where the overall improbement will be significant. Tweaking a loop to run in 5% of the original time will be an insignificant gain if only 1% of the total time was spent in the loop. Thus what appeared at first to increase the speed of execution by a factor of 20 would, in that case reduce overall execution time by less than 1%.
FZB edited Revision 16. Comment: typo