Вопрос стиля PHP: «кэширование» значений объекта / массива в переменной? - PullRequest
2 голосов
/ 11 июня 2011

Пожалуйста, спасите меня от себя (или убедите меня, что я не полностью заблуждаюсь)

У меня появилась привычка писать код примерно так:

function foo($aUserObject) {
    $theUserUID = $aUserObject->uid;
    $aDeepValue = $aUserObject->property[123][456];
    [more code, in which much use is made of $theUserUID and $aDeepValue]
}

Моя стратегия, вероятно, очевидна: я придерживаюсь мнения, что интерпретатору PHP будет легче обрабатывать ссылку на переменную, чем постоянно копаться в объекте, чтобы найти интересующую меня вещь, поэтому мне следует получать некоторое преимущество в производительности. Кроме того, мой код, возможно, немного более свободен от ошибок и понятен (если я помню значения имен переменных), так как я в основном пишу простые имена переменных, а не более длинные и более сложные ссылки на объекты / массивы, где мой пальцы, скорее всего, поскользнутся. Я понимаю, что для этого есть цена - теперь существует две копии $aUserObject->uid и $aUserObject->property[123][456], и, если эти значения большие, дополнительные затраты памяти могут возрасти. Но в настоящее время я готов заплатить эту цену в обмен на (предполагаемые) льготы.

Или, в любом случае, я сам себе это говорю, основываясь на своей наивной теории о том, как работает PHP. Но реальность, особенно когда внедряются инструменты кэширования кода операции, такие как APC, может быть совершенно другим вопросом. Есть ли более информированные мнения, которые могут подтолкнуть меня так или иначе?

Спасибо!

Ответы [ 4 ]

4 голосов
/ 11 июня 2011

Я могу вас заверить, вы ошибаетесь, когда говорите:

Я понимаю, что для этого есть цена - теперь есть две копии $ aUserObject-> uid и $ aUserObject-> property [123] [456], и если эти значения велики, дополнительная память расходы могут сложиться.

Если $theUserUID не изменено или на него не ссылаются, оно указывает на точно такую ​​же ячейку памяти , из которой было выбрано свойство.

Вы даже можете сделать:

$a = $b = $c = $d = $e = 'hello world!';

И это не займет больше памяти, чем:

$a = 'hello world!';

Копия будет создана в следующих сценариях:

$a = 1;
$b = $a;  // $b references $a
$b = 2;   // $b is now a copy (no longer references $a)

$a = 1;
$b = $a;  // $b references $a
$c = &$b; // $b is now a copy (no longer references $a)

Это называется копирование при записи .

Совет: попробуйте debug_zval_dump и memory_get_usage и обратите внимание, что refcount увеличивается, в то время как использование памяти остается прежним.

1 голос
/ 11 июня 2011

Поправь меня, если я ошибаюсь, но я верю, что ты что-то не так.

there are now two copies of $aUserObject->uid and $aUserObject->property[123][456] floating around, and if those values are large, the additional memory costs could add up.

Будет еще одна ссылка на значение, но это НЕ означает, что оно будет занимать вдвое больший объем памяти. Это как реляционная база данных, вы можете добавить множество ссылок на один и тот же элемент, но только сами ссылки будут сохранены более одного раза.

0 голосов
/ 11 июня 2011

Мне кажется, это хорошо. Но только в качестве второго пункта.

Я предлагаю:

  1. Убедитесь, что ваш код читабелен и понятен (документация, правильное именование переменных, руководящие указания по стилю кода и т. Д.).
  2. Ищите современные или новые стандарты в будущем (здесь php) и следуйте им!
  3. Повторное использование: это преимущество пунктов 1 и 2.
  4. Вопросы производительности следует обсуждать - но на уровне алгоритмического / проектного шаблона, а не на основе глубокого кода. В финальной реализации просто убедитесь, что вы правильно ее реализовали.
  5. Оптимизация: только если возникают проблемы с производительностью, подумайте о глубокой оптимизации кода. Но будьте уверены, что это понятно и читабельно. В противном случае код станет бесполезным в будущем.
0 голосов
/ 11 июня 2011

Более понятный код - это большой плюс, если вы планируете его поддерживать.

Конечно, некоторые подпрограммы могут требовать большего внимания к проблемам памяти / производительности, чем другие, но если выимеют дело с большими объемами данных, выгоды вполне стоят (возможных) затрат.

кстати, вы также можете использовать ссылки:

$theUserUID = &$aUserObject->property[123][456];
$theUserUID = 'someValue'; // updates $aUserObject 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...