Welcome to MSDN Blogs Sign in | Join | Help

PowerShell, performance and regular expressions

Yesterday evening, I started to read Windows PowerShell in Action and did confirm what I had already read here and there: it’s a good book!

 

 So this morning, I was playing around and trying some of the stuff I had read:

 

> Get-Process | Get-Member

 

   TypeName: System.Diagnostics.Process

 

Name                           MemberType     Definition

----                           ----------     ----------

Handles                        AliasProperty  Handles = Handlecount

Name                           AliasProperty  Name = ProcessName

NPM                            AliasProperty  NPM = NonpagedSystemMemorySize

PM                             AliasProperty  PM = PagedMemorySize

VM                             AliasProperty  VM = VirtualMemorySize

WS                             AliasProperty  WS = WorkingSet

add_Disposed                   Method         System.Void add_Disposed(EventHandler value)

add_ErrorDataReceived          Method         System.Void add_ErrorDataReceived(DataReceivedEventHandler value)

add_Exited                     Method         System.Void add_Exited(EventHandler value)

add_OutputDataReceived         Method         System.Void add_OutputDataReceived(DataReceivedEventHandler value)

BeginErrorReadLine             Method         System.Void BeginErrorReadLine()

BeginOutputReadLine            Method         System.Void BeginOutputReadLine()

CancelErrorRead                Method         System.Void CancelErrorRead()

CancelOutputRead               Method         System.Void CancelOutputRead()

Close                          Method         System.Void Close()

CloseMainWindow                Method         System.Boolean CloseMainWindow()

CreateObjRef                   Method         System.Runtime.Remoting.ObjRef CreateObjRef(Type requestedType)

Dispose                        Method         System.Void Dispose()

Equals                         Method         System.Boolean Equals(Object obj)

GetHashCode                    Method         System.Int32 GetHashCode()

GetLifetimeService             Method         System.Object GetLifetimeService()

GetType                        Method         System.Type GetType()

get_BasePriority               Method         System.Int32 get_BasePriority()

 

I did not want to see those [get|set|add|remove]_ … methods! So I try something quick:

Get-Process | Get-Member | ? {$_.Name.IndexOf('_') -eq -1}

 

But this would leave other members out (e.g. __NounName) so I changed it to:
Get-Process | Get-Member | ? {$_.Name.IndexOf('_') -lt 1}

 

But I would still miss some members so I went for the more precise stuff:
Get-Process | Get-Member | ? {$n = $_.Name; -not $n.StartsWith('get_') -and -not $n.StartsWith('set_') -and -not  $n.StartsWith('add_') -and -not $n.StartsWith('remove_')}

 

I then decided to send it to an internal distribution list dedicated to PowerShell asking for any help to make it shorter and/or faster. Alex answered with the following:

… | gm | ?{ !($_.Name -match "^(get|set|add|remove)_") }

 

I replied that it was indeed shorter but slower. Pressing the Send button, I thought “Never say such things without measuring”. But I’m lazy…

 

17 minutes later, he answered again:

1..100 | measure-command { ls | … } gives 5.34 sec for your version and 4.72 for mine.

 

If you think that the file system caching might have something to do with those results, try with processes: his solution is still faster.

 

Thanks Alex!

 

> 1..100 | measure-command { get-process | gm | ?{ !($_.Name -match "^(get|set|add|remove)_") } }

 

Days              : 0

Hours             : 0

Minutes           : 0

Seconds           : 13

Milliseconds      : 353

Ticks             : 133534572

TotalDays         : 0.000154553902777778

TotalHours        : 0.00370929366666667

TotalMinutes      : 0.22255762

TotalSeconds      : 13.3534572

TotalMilliseconds : 13353.4572

 

> 1..100 | measure-command { get-process | gm | ? {$n = $_.Name; -not $n.StartsWith('get_') -and -not $n.StartsWith('set_') -and -not  $n.StartsWith('add_') -and -not $n.StartsWith('remove_')} }

 

Days              : 0

Hours             : 0

Minutes           : 0

Seconds           : 15

Milliseconds      : 536

Ticks             : 155367665

TotalDays         : 0.000179823686342593

TotalHours        : 0.00431576847222222

TotalMinutes      : 0.258946108333333

TotalSeconds      : 15.5367665

TotalMilliseconds : 15536.7665

Published Thursday, February 22, 2007 2:17 PM by yvesdolc

Comments

Anonymous comments are disabled
 
Page view tracker