возвращать большие данные по ссылке или как возврат в функцию?

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

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 ()»

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

Это связано с тем, как 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/