2016-04-15 4 views
0

У меня есть следующие If блок, который в сценарии входа в систему, который я переписывания:переключатель против If-Else Performance

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" 
} 

который, очевидно, должен быть переписан как If/Else заявление (как каждый пользователь только 1 имя) Тем не менее, я предпочитаю вид следующего switch -Regex метода:

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} 
} 

Мой вопрос - будет с помощью переключателя таким образом, имеют какое-либо влияние на производительность этой функции? Это должно быть лучше, чем указано выше (if/if/if), поскольку не каждая возможность оценивается каждый раз, но будет ли switch быстрее, чем ifelse/ifelse/else?

+0

Возможно, вы захотите использовать группы, а не тестировать пользователей один за другим, но что я не применим к вашей ситуации. – sodawillow

+0

@sodawillow Спасибо за ваш комментарий. Я тестирую группы в другом месте сценария, но установка, которая выполняется здесь, уникальный для этих пользователей, поэтому это кажется лучшим способом в моем случае – Bassie

+0

[Связанный, если не обман] (http://stackoverflow.com/questions/445067/if-vs-switch-speed) – Matt

ответ

1

Я написал этот тест, чтобы проверить, если я мог бы выяснить, какой путь лучше, используя 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" 
} 

Результаты

В среднем, это то, как каждая функция выполняется в 10000 тестов:

Switch - 11592,8566

IfElse - 15740.3281

Результаты оказались не самыми последовательными (иногда switch был быстрее, иногда ifelse был быстрее), но как switch быстрее в целом (в среднем в среднем) я буду использовать это вместо ifelse.

Получу любую отзыв об этом решении и моем тестировании.

1

Как правило, операторы switch работают путем построения таблицы перехода в коде сборки и использования этого для определения соответствующего маршрута вместо использования компараторов типа if/else. Вот почему операторы switch быстрее. Я считаю, что со строками компилятор генерирует хеш-код строк и использует это для реализации таблицы переходов, чтобы оператор switch был быстрее. Таким образом, оператор switch должен быть быстрее, чем if/if /, если вы написали выше, но это может быть не так, поскольку операторы switch обычно полагаются на варианты, которые несколько равномерно распределены (например, 1 2 3 или 5 10 15).

С учетом этого, почему бы вам не использовать if/else-if/else-if вместо if/if/if? Это определенно будет быстрее, поскольку каждый параметр оценивается каждый раз.

+0

Вы уверены, что это применимо в равной степени на динамический/интерпретируемый язык, такой как PowerShell? Как бы вы даже реализовали таблицу перехода на основе хэша для коммутатора, поддерживающего соответствие шаблону регулярного выражения? –

+0

@Ryan Спасибо за ваш ответ. Я решил выбрать «переключатель» на основе некоторого тестирования (см. Мой собственный ответ). Считаете ли вы, что эти тесты являются допустимым способом определения того, какая инструкция выполняется быстрее? – Bassie

Смежные вопросы