2015-08-03 2 views
1

Я пытаюсь понять zavas. Поэтому рассмотрим следующий код:пытаясь понять zpамы php

<?php 
$randomByteString = 'abcd'; 

$val = 0; 
for ($i = 0; $i < 4; ++$i) { 
    $val |= ord($randomByteString[$i]) << ($i * 8); 
} 

echo $val; 

Мне кажется, что Zval будет создана для каждого из этих утверждений:

  • $ я = 0
  • ++ $ я
  • $ я * 8
  • $ randomByteString [$ я]
  • Ord ($ randomByteString [$ я])
  • и при любом изменении на $ val

Это правильно?

+0

Нет, зачем нужно создавать новый zval для '++ $ i', когда уже существует zval для' $ i'? Все, что вы делаете, это изменение значения, хранящегося в этом zval –

+0

Аналогично для изменений в '$ val' вы меняете существующее значение в существующем zval, поэтому нет необходимости создавать новый zval –

+0

. Существует [целое раздел в руководстве] (http://php.net/manual/en/internals2.variables.intro.php) о них. –

ответ

3

Не совсем. Давайте перейдем к этому по очереди, опираясь на то, как PHP 5 будет обрабатывать эти zvals.

<?php 
$randomByteString = 'abcd'; 

Новый Zval содержащий 'abcd' создан и теперь $randomByteString указывает на него.

ZVAL подсчитывать до сих пор: 1

$val = 0; 

Новый Zval содержащий 0 создан и теперь $val указывает на него.

Zval подсчитывать до сих пор: 2

for ($i = 0; $i < 4; ++$i) { 

В первый раз мы бежим через это, мы создаем ZVAL для 0 и точки $i к нему.

Сравнение $i и 4 может временно создать булевский zval. Моя память о том, что делает PHP 5 здесь, нечеткая, возможно, она не будет делать это под капотом. Это не имеет значения для нашего общего подсчета, потому что это будет немедленно выброшено.

Incrementing $i не создает zval, он просто меняет число внутри zval $i.

Zval подсчитывать до сих пор: 3 (не включая временную ZVAL, как это было выброшено)

$val |= ord($randomByteString[$i]) << ($i * 8); 

Доступ $randomByteString[$i] создаст ZVAL, содержащий строку однобайтной. Передавая его ord(), он отбросит это zval и создаст новый zval, содержащий целое число.

Умножая его 8 на $i создаст новый zval.

В результате сдвига нашего ord() результат $i приведет к созданию нового zval и отбросит наши два входных сигнала.

И наконец, используя |= с $val, вы измените значение в $val и отбросьте наш результат с левой стороны.$val уже существует, поэтому мы просто меняем содержимое, а не делаем для него новый zval.

ZVAL подсчитывать до сих пор: 4

} 

echo $val; 

Echo не будет создавать zvals.

В конце скрипта у вас есть 4 знака вокруг.

К слову, zvals создан для $i < 4, $randomByteString[$i], ($i * 8) и << все временных zvals: они не вызывают новые распределения памяти, вместо того, чтобы они хранятся в специальной области памяти, используемой для временных значений , Это означает, что для создания этих временных значений не существует штрафа за производительность. Другие zvals (в том числе ord() по какой-либо причине, вызовы функций неэффективны), с другой стороны, требуют выделения памяти.

Кроме того, все это только для PHP 5. PHP 7 обрабатывает zvals намного более умным образом, так что обычно для них не требуется выделенных выделенных памяти.

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