2013-03-02 1 views
1

У меня есть вложенная-если подобный кодкак сделать лучший код из этих вложенных, если условий

if (condition1 or condition2 or condition3) { 
      if (condition1) { 
      } 
      elsif (condition2) { 
      } 
      elsif (condition3) { 
      } 
} 

Теперь, очевидно, условие (1,2 и 3) уже проверен на внешнем if, так Я не хочу, чтобы они снова проверялись во внутренних if-elsif заявлениях. Так что мой раствор был, полностью удалив внешний if. Но опять же это пройдёт через if-elsif.

Так что, если есть 10-15 условий. Какая из них лучше? Или есть ли другое лучшее решение?

ответ

3

Внешняя if не является обязательной.

Кроме того, только три возможные оптимизации кажутся разумными:

  1. профиля коды перед оптимизацией, и сортировки, если/иначе условия так, что наиболее распространенное заболевание испытываются первыми и т.д.
  2. Используйте структуры данных для представления условий. В случае, если вы будете испытывать для какого-то равенства (if ($foo eq $bar){...}elsif($foo eq $baz){...}), то хэш может преобразовать поиск от линейного к постоянная времени:

    %hash = ($bar => sub{...}, $baz => sub{...}); 
    my $code = $hash{$foo} or do{"this is the trailing else"}; 
    $code->(); # execute the coderef 
    

    Это дико гибкое, но включает в себя косвенность закрытий.

  3. Если вам нужно пересмотреть условие, кешируйте результат. Область действия переменной, которая была объявлена ​​в состоянии достигает во всех последующих условий и блоков, если/еще цепи:

    if (my $cond1 = ... and ...) { 
        ... 
    } elsif ($cond1 and my $cond2 = ...) { 
        ... 
    } elsif ($cond2) { 
        ... 
    } 
    
+1

Хеш - мой выбор для многих условий 'if', при условии равенства. – 2013-03-02 07:29:08

2

Это зависит от того, как часто ваш код выполняется. Со сложными наборами if-утверждений лучше оптимизировать для удобочитаемости, поскольку по сравнению с большинством других операций они дешевы. Однако, в вашем примере выше, я бы вообще удалил внешнее утверждение, это просто не нужно. Perl оптимизирует код, пока он разбирает его в любом случае.

+0

Это было хорошо для оптимизации perl. Я лучше удаляю внешний, если тогда и использую хеш, если возможно, для нескольких ifs. – 2013-03-02 07:30:51

1

возможно управление переключатель предложение может иметь смысл в коде (в зависимости от условия, которые вы проверяете). Взгляните на documentation of Switch.

Update Начиная с версии 5.10 PERL, есть given/when control flow.

use feature "switch"; 
+0

Это выше 5.10? Я должен это проверить. Я нашел его, хотя. – 2013-03-02 07:33:27

+4

Модуль коммутатора устарел. Функция 'given/when' - это замена,' use feature 'switch''. – TLP

+1

Я проверил и по причинам фильтрации источников (модуль, который влияет на то, как будет использоваться синтаксический анализ файла. Они обычно используются для имитации синтаксических функций, которые Perl не имеет изначально), case switch больше не используется , 'given/when' является заменой – 2013-03-02 08:06:22

0
  1. Удалить внешние if заявления, потому что все условия будут проверены все равно внутренними if заявления.

  2. Если вы согласны с тем, какие условия в соответствии с приоритетом, как в condition1, важнее, чем condition2, то, разумеется, вы не можете изменить порядок проверок.

  3. Если вы устраиваете какие-либо условия в соответствии с частотой возникновения, то вы можете изменить их на частоту, когда вы тестируете или проецируете программу.

  4. Если условие1 истинно, тогда запустите statement1. Если ваши заявления слишком длинные, тогда их следует добавить в подпрограммы и вызвать их, чтобы они выглядели аккуратно.

    if (condition1) {&run_statement1();} 
    elsif (condition2) {&run_statement2();} 
    elsif (condition3) {&run_statement3();} 
    elsif (condition4) {&run_statement4();} 
    elsif (condition5) {&run_statement5();} 
    elsif (condition6) {&run_statement6();} 
    elsif (condition7) {&run_statement7();} 
    else    {&run_elsestatement();} 
    
  5. Не излишне усложняйте и не запутывайте код. Держите его простым, читаемым и выполняющим ваши цели.

2

Если ваши условия являются все тесты по стоимости одной и той же переменной, вы можете использовать given/when в 5.10.1 Perl и позже:

use 5.010; 

given ($foo) { 
    when ('bar') { ... }     # string literal 
    when (4) { ... }      # numeric literal 
    when (qw[ xyzzy plugh ]) { ... }  # any of multiple literals 
    when (/^whee+$/) { ... }    # regex match 
    default { ... }      # fallthrough if nothing matched 
} 
+0

Интересно. Раньше я об этом не знал. – ruben2020

+0

Опасайтесь использования этой конструкции, поскольку есть разговоры об ее удалении. Он полагается на оператор smart-match '~~', который имеет недостатки. – Borodin

0

Или это:

(condition1) ? run_statement1() : 
(condition2) ? run_statement2() : 
(condition3) ? run_statement3() : run_elsestatement() ; 

Я поклонник менее типизации. Другой вариант, если ваши оцениваемые условия создают «уникальные» результаты, заключается в использовании результата в качестве ключа в хеш-функции. Это полностью отменяет условную проверку.

Например, если условия были основаны на значении, хранящемся в скаляре с именем «$ var», тогда вы можете просто использовать эти разные значения в качестве ключей к хэшу.

$conditionalFunctionHash{$var}->(); 
Смежные вопросы