2015-02-20 5 views
-1

Мне просто интересно, как PHP работает под капотом в этом определенном сценарии. Скажем, у меня есть эти два фрагмента кода:PHP поведение под капотом

function foo() { 
    return 2 * 2; 
} 

// First. 
if (foo()) { 
    bar(foo()); 
} 

// Second. 
if (($ref = foo())) { 
    bar($ref); 
} 

Теперь вопросы:

  1. В первом случае, это PHP сделать какую-то временную переменную внутри, если п? Если да, то не второй ли код всегда лучше подходит?

  2. Имеет ли второй корпус больше памяти? Если ответ на первый вопрос дается на первый вопрос, то нет?

+0

Вы должны использовать только первый, если хотите называть 'foo()' дважды. – Barmar

ответ

0
  1. В первом случае, вы вызываете функцию дважды, так что, если функция отнимает много времени, это неэффективно. Второй случай действительно лучше, так как вы сохраняете результат foo().

  2. В обоих случаях PHP должен выделять память в зависимости от того, какие данные генерирует foo(). Впоследствии память будет освобождена сборщиком мусора. С точки зрения памяти оба случая в значительной степени эквивалентны. Возможно, память будет выпущена раньше, может быть, нет, но, скорее всего, вы не столкнетесь с ситуацией, когда это имеет значение.

0

PHP не может делать какие-либо временную переменную, поскольку она не может быть уверен, что foo() «s возвращающие значение всегда будет то же самое. microtime(), rand() возвратит различные значения для каждого вызова, например.

Во втором примере требуется больше памяти, поскольку PHP необходимо создать и сохранить значение в памяти.

Вот как проверить:

<?php 

function foo() { 
    return true; 
} 

function bar($bool) { 
    echo memory_get_usage(); 
} 

if (1) { 
    // 253632 bytes on my machine 
    if (foo()) { 
     bar(foo()); 
    } 
} else { 
    // 253720 bytes on my machine 
    if (($ref = foo())) { 
     bar($ref); 
    } 
} 
1

Эти два кода не эквивалентны, так как первый один называет foo() дважды (если она возвращает значение truthy). Если у него есть побочные эффекты, такие как печать чего-то, они будут выполняться дважды. Или, если это зависит от того, что может измениться (например, содержимое файла или базы данных), два вызова могут возвращать разные значения. В вашем примере, где он просто умножает два числа, этого не происходит, но это все равно означает, что он должен делать дополнительное умножение, что не нужно.

Ответ на ваши вопросы есть:

  1. Да, он должен держать возвращаемое значение во временной ячейке памяти, чтобы он мог проверить, правда это или нет.

  2. Да, он использует немного больше памяти. В первой версии временная память может быть восстановлена, как только будет завершен тест if. Во второй версии он не будет возвращен до тех пор, пока переменная $foo не будет переназначена или выходит за рамки.

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