вернуть большие данные по ссылке или как вернуть в функцию? - PullRequest
11 голосов
/ 24 мая 2011

Сегодня на работе у меня был спор с коллажем о передаче больших данных между областями.Миф состоял в том, что ссылка использует меньше памяти / ЦП при переходе между двумя областями.Мы создаем доказательство того, кто был прав ... так:

function by_return($dummy=null) {
    $dummy = str_repeat("1",100 * 1024 * 1024);
    return $dummy;
}

function by_reference(&$dummy) {
    $dummy = null;
    $dummy = str_repeat("1",100 * 1024 * 1024);
}
echo memory_get_usage()."/".memory_get_peak_usage()."\n";
//1 always returns: 105493696/105496656
$nagid = by_return();
echo memory_get_usage()."/".memory_get_peak_usage()."\n";
unset($nagid);
//2 always returns:  105493696/210354184 even if we comment 1st part
by_reference($dummy);
echo memory_get_usage()."/".memory_get_peak_usage()."\n";
unset($dummy);

Но похоже, что по ссылке он потребляет больше памяти в соответствии с функцией "memory_get_peak_usage ()"

Использование больших данных для возврата намного умнее, чем использование в качестве ссылки, но вопрос в том, почему?Любое просвещение приветствуется:)

1 Ответ

9 голосов
/ 24 мая 2011

Это связано с тем, как php обрабатывает переменные, и немного нелогично для всех, кто работал на C или C ++.

Переход по ссылке, чтобы быть умнее, чем PHP, не рекомендуется. На самом деле PHP не делает копии данных, если в этом нет необходимости (т.е. вы меняете значение переменной, когда на нее более 1 ссылки), стратегия оптимизации очень похожа на копирование при записи для страниц с общей памятью.

Итак, допустим, у вас есть переменная, которую вы передаете по значению несколько раз в данном скрипте. Если вы затем возьмете эту переменную и передадите ее по ссылке, вы фактически дублируете переменную, а не просто получаете указатель на объект.

Это связано с тем, что внутренне PHP zvals (структура данных, которую PHP использует для хранения переменных) может быть только ссылочными или не ссылочными переменными. Поэтому не имеет значения, что представляет собой поле ref_count в zval, потому что это не ссылочная переменная (поле is_ref структуры zval). Поэтому внутренне PHP вынужден создавать новый zval и устанавливать для его поля is_ref значение true, что удваивает объем памяти.

Скажите вашему коллеге, чтобы он прекратил попытки перехитрить PHP. Передача по ссылке, если она не выполнена на 100% по всему коду, приведет к большим накладным расходам и удвоит использование памяти.

Для более подробного обсуждения, пожалуйста, перейдите по этой ссылке: http://porteightyeight.com/2008/03/18/the-truth-about-php-variables/

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