eval () и if () - есть ли разница в производительности? - PullRequest
0 голосов
/ 05 августа 2011

Мой вопрос специально относится к Perl, но я бы хотел быть просвещенным для большинства языков.

Существует ли реальная разница (с точки зрения производительности и эффективности) между использованием функции eval () и оператора if ()?

eval(-e /path/to/file) or die "file doesn't exist";
if (! -e /path/to/file) { die "file doesn't exist"; }

Ответы [ 2 ]

6 голосов
/ 05 августа 2011

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

Тем не менее, вы можете проверить, как perl компилирует такие вещи:

$ perl -MO=Concise,-exec -e '-e "/path/to/file" or die "file doesn\x27t exist";'
1  <0> enter 
2  <;> nextstate(main 1 -e:1) v:{
3  <$> const[PV "/path/to/file"] s
4  <1> ftis sK/1
5  <|> or(other->6) vK/1
6      <0> pushmark s
7      <$> const[PV "file doesn't exist"] s
8      <@> die[t2] vK/1
9  <@> leave[1 ref] vKP/REFC
-e syntax OK

$ perl -MO=Concise,-exec -e 'if ( ! -e "/path/to/file") { die "file doesn\x27t exist"; }'
1  <0> enter 
2  <;> nextstate(main 3 -e:1) v:{
3  <$> const[PV "/path/to/file"] s
4  <1> ftis sK/1
5  <1> not sK/1
6  <|> and(other->7) vK/1
7      <0> enter v
8      <;> nextstate(main 1 -e:1) v:{
9      <0> pushmark s
a      <$> const[PV "file doesn't exist"] s
b      <@> die[t2] vK/1
c      <@> leave vKP
d  <@> leave[1 ref] vKP/REFC
-e syntax OK

Вы можете увидеть некоторые тривиальные дополнительные операции, включенные во вторую, для логического не результата -e, входа и выхода из блока {}, а также для того, чтобы иметь штамп как отдельный оператор.Это отдельное утверждение может быть полезным;если вы шагаете по коду в отладчике, он останавливается перед смертью.

Использование Perl 5.12+ или использование unless вместо if ! в более старой версии Perl удаляет not:

$ perl -MO=Concise,-exec -e 'unless (-e "/path/to/file") { die "file doesn\x27t exist"; }'
1  <0> enter 
2  <;> nextstate(main 3 -e:1) v:{
3  <$> const[PV "/path/to/file"] s
4  <1> ftis sK/1
5  <|> or(other->6) vK/1
6      <0> enter v
7      <;> nextstate(main 1 -e:1) v:{
8      <0> pushmark s
9      <$> const[PV "file doesn't exist"] s
a      <@> die[t2] vK/1
b      <@> leave vKP
c  <@> leave[1 ref] vKP/REFC
-e syntax OK

Использование модификатора оператора приводит к тем же результатам, что и код -e ... or die:

$ perl -MO=Concise,-exec -e 'die "file doesn\x27t exist" unless -e "/path/to/file";'
1  <0> enter 
2  <;> nextstate(main 1 -e:1) v:{
3  <$> const[PV "/path/to/file"] s
4  <1> ftis sK/1
5  <|> or(other->6) vK/1
6      <0> pushmark s
7      <$> const[PV "file doesn't exist"] s
8      <@> die[t2] vK/1
9  <@> leave[1 ref] vKP/REFC
-e syntax OK
2 голосов
/ 05 августа 2011

Строка eval (eval EXPR) требует, чтобы perl компилировал ваше выражение во время выполнения при каждом его выполнении, что будет намного дороже, чем оценка предварительно скомпилированного выражения.Это также справедливо для любого языка, который предоставляет аналогичный механизм оценки во время выполнения (JavaScript, Ruby, Python?)

И в строке eval, и в блоке eval (eval { BLOCK }), perlустанавливает обработчик ошибок, который устанавливает $@ и возвращает в конец оператора eval в случае фатальной ошибки в противном случае.Опять же, это дороже, чем просто выполнить BLOCK на Perl и на любом другом языке с возможностью перехвата исключений (Python, Java).

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