Perl: почему оператор if медленнее, чем "и"? - PullRequest
2 голосов
/ 18 сентября 2008

В Perl условное выражение может быть выражено как

if (condition) { do something }

или как

(condition) and do { do something }

Интересно, что второй способ кажется примерно на 10% быстрее. Кто-нибудь знает почему?

Ответы [ 6 ]

18 голосов
/ 18 сентября 2008

Ниже приведены некоторые комментарии о смерти:

Во-первых, не используйте B :: Terse, он устарел. B :: Concise дает вам гораздо лучшую информацию, когда вы к ней привыкли.

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

В-третьих, нет никакого дополнительного кода операции - «ноль» указывает на код операции, который был оптимизирован (полностью вне дерева выполнения, хотя все еще в дереве разбора).

Вот краткое дерево выполнения для двух случаев, которое показывает их как идентичные:

$ perl -MO=Concise,-exec -e'($condition) and do { do something }'
1  <0> enter 
2  <;> nextstate(main 2 -e:1) v
3  <#> gvsv[*condition] s
4  <|> and(other->5) vK/1
5      <$> const[PV "something"] s/BARE
6      <1> dofile vK/1
7  <@> leave[1 ref] vKP/REFC
-e syntax OK
$ perl -MO=Concise,-exec -e'if ($condition) { do something }'
1  <0> enter 
2  <;> nextstate(main 3 -e:1) v
3  <#> gvsv[*condition] s
4  <|> and(other->5) vK/1
5      <$> const[PV "something"] s/BARE
6      <1> dofile vK/1
7  <@> leave[1 ref] vKP/REFC
-e syntax OK
11 голосов
/ 18 сентября 2008

Это просто показывает, что если вы не знаете, как правильно выполнять профилирование кода, не занимайтесь этим. Разница в скорости этих двух методов находится в пределах одной и той же скорости Big O () (как доказано анализом кода @Leon Timmermans) - тесты просто покажут различия на основе других локальных условий, а не обязательно вашего кода.

@ Сванте сказал, что «и» было быстрее, а @shelfoo сказал «если» быстрее.

Я имею в виду, действительно ... 7 сотых секунды за 10 миллионов циклов? Это не быстрее и не медленнее, статистически ... это равно.

Вместо того, чтобы смотреть на такие мелкие моменты времени, как это, вы узнаете о рефакторинге кода и нотации Big O () ... как уменьшить количество циклов в вашем коде ... и, самое главное, как использовать профилировщики кода для где настоящие узкие места. Не беспокойтесь о статистически незначимых вещах. ;)

11 голосов
/ 18 сентября 2008

Я удалился, и это действительно не должно быть быстрее. Дерево кода операции для первого -

LISTOP (0x8177a18) leave [1] 
    OP (0x8176590) enter 
    COP (0x8177a40) nextstate 
    LISTOP (0x8177b20) scope 
        OP (0x81779b8) null [174] 
        UNOP (0x8177c40) dofile 
            SVOP (0x8177b58) const [1] PV (0x81546e4) "something" 

Дерево кода операции для второго -

LISTOP (0x8177b28) leave [1] 
    OP (0x8176598) enter 
    COP (0x8177a48) nextstate 
    UNOP (0x8177980) null 
        LISTOP (0x8177ca0) scope 
            OP (0x81779c0) null [174] 
            UNOP (0x8177c48) dofile 
                SVOP (0x8177b60) const [1] PV (0x81546e4) "something"

Я действительно не понимаю, как последний может быть быстрее. Это делает код операции больше!

3 голосов
/ 18 сентября 2008

Сколько тестов вы сделали, прежде чем усреднить? Очень, очень маленькие отклонения статистически незначимы! Существует множество причин, по которым скорость может незначительно отличаться между тестами.

2 голосов
/ 18 сентября 2008

Согласно Benchmark, второе немного медленнее. Возможно, это как-то связано с условием, но вот результаты для очень простого случая:


use Benchmark;

timethese(10000000, {
    'if' => '$m=5;if($m > 4){my $i=0;}',
    'and' => '$m=5; $m > 4 and do {my $i =0}',
});

Результаты:


Benchmark: timing 10000000 iterations of Name1, Name2...
     if:  3 wallclock secs ( 2.94 usr +  0.01 sys =  2.95 CPU) @ 3389830.51/s (n=10000000)
     and:  3 wallclock secs ( 3.01 usr +  0.01 sys =  3.02 CPU) @ 3311258.28/s (n=10000000)

0 голосов
/ 18 сентября 2008

Это также может зависеть от версии Perl. Который вы не упомянули. И разницы не достаточно, чтобы беспокоиться в любом случае. Поэтому используйте все, что имеет больше смысла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...