Reputation: 10390
I have the following If
block which in a logon script which I am re-writing:
If ($distinguishedname -match 'Joe Bloggs') {
Map-Drive 'X' "\\path\to\drive"
}
If ($distinguishedname -match 'Steve Bloggs') {
Map-Drive 'X' "\\path\to\drive"
}
If ($distinguishedname -match 'Joe Jobs') {
Map-Drive 'X' "\\path\to\drive"
}
Which obviously needs to be re-written as an If/Else
statement (as each user only has 1 name!) However, I prefer the look of the following switch -Regex
method:
switch -Regex ($distinguishedname) {
'Joe Bloggs' {Map-Drive 'X' "\\path\to\drive"; break}
'Steve Bloggs' {Map-Drive 'X' "\\path\to\drive"; break}
'Joe Jobs' {Map-Drive 'X' "\\path\to\drive"; break}
}
My question is - would using a switch in this manner have any impact on the performance of this function? It must be better than the above (if/if/if
), as not every possibility is evaluated each time, but would the switch
be faster than an ifelse/ifelse/else
?
Upvotes: 3
Views: 8843
Reputation: 10390
I wrote this test to check if I could figure out which way is better using Measure-Command
:
function switchtest {
param($name)
switch -Regex ($name) {
$optionsarray[0] {
Write-host $name
break
}
$optionsarray[1] {
Write-host $name
break
}
$optionsarray[2] {
Write-host $name
break
}
$optionsarray[3] {
Write-host $name
break
}
$optionsarray[4] {
Write-host $name
break
}
default { }
}
}
function iftest {
param($name)
If ($name -match $optionsarray[0]) {Write-host $name}
ElseIf ($name -match $optionsarray[1]) {Write-host $name}
ElseIf($name -match $optionsarray[2]) {Write-host $name}
ElseIf($name -match $optionsarray[3]) {Write-host $name}
ElseIf($name -match $optionsarray[4]) {Write-host $name}
}
$optionsarray = @('Joe Bloggs', 'Blog Joggs', 'Steve Bloggs', 'Joe Jobs', 'Steve Joggs')
for ($i=0; $i -lt 10000; $i++) {
$iftime = 0
$switchtime = 0
$rand = Get-Random -Minimum 0 -Maximum 4
$name = $optionsarray[$rand]
$iftime = (Measure-Command {iftest $name}).Ticks
$switchtime = (Measure-Command {switchtest $name}).Ticks
Add-Content -Path C:\path\to\outfile\timetest.txt -Value "$switchtime`t$iftime"
}
Results
On average, this is how each function performed in 10,000 tests:
Switch - 11592.8566
IfElse - 15740.3281
The results were not the most consistent (sometimes switch
was faster, sometimes ifelse
was faster) but as switch
is faster overall (on mean average) I will be using this instead of ifelse
.
Would appreciate any feedback on this decision and my testing.
Upvotes: 8
Reputation: 1221
Typically, switch statements work by building a jump table in the assembly code and using that to determine the appropriate route instead of using comparators like if/else. That's why switch statements are faster. I believe that with strings, the compiler generates a hash code of the strings and uses that to implement the jump table so that the switch statement is still faster. So the switch statement should be faster than the if/if/if you have written above but it may not be since switch statements typically rely on the options being somewhat evenly spaced (e.g. 1 2 3 or 5 10 15).
With that being said, why don't you use an if/else-if/else-if instead of an if/if/if? That'll definitely be faster since not every option is evaluated each time.
Upvotes: 3