У меня есть огромное количество объектов PHP для нейронной сети, для которой я должен перебирать и выполнять некоторые математические вычисления. Мне было интересно, не лучше ли мне использовать ассоциативный массив над экземплярами классов?
Я занимаюсь примерно 3640
объектами и итерации примерно 500
раз (в лучшем случае), поэтому любая микро-оптимизация помогает. Было бы неизбежно быстрее сделать $object['value']
чем $object->value
?
Изменить: Таким образом, они оба одинаковы. Но я думаю, что для конструктора будет немного накладных расходов? В любом случае, я не думаю, что хочу обменять мои красивые классы на грязные массивы: P
Основанный на коде Quazzle, я запускал следующий код (5.4.16 windows 64bits):
<?php class SomeClass { public $aaa; public $bbb; public $ccc; } function p($i) { echo '<pre>'; print_r($i); echo '</pre>'; } $t0 = microtime(true); $arraysOf=array(); $inicio=memory_get_usage(); for ($i=0; $i<1000; $i++) { $z = array(); for ($j=0; $j<1000; $j++) { $z['aaa'] = 'aaa'; $z['bbb'] = 'bbb'; $z['ccc'] = $z['aaa'].$z['bbb']; } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>arrays: '.(microtime(true) - $t0)."</p>"; echo '<p>memory: '.($fin-$inicio)."</p>"; p($z); $t0 = microtime(true); $arraysOf=array(); $inicio=memory_get_usage(); for ($i=0; $i<1000; $i++) { $z = new SomeClass(); for ($j=0; $j<1000; $j++) { $z->aaa = 'aaa'; $z->bbb = 'bbb'; $z->ccc = $z->aaa.$z->bbb; } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>arrays: '.(microtime(true) - $t0)."</p>"; echo '<p>memory: '.($fin-$inicio)."</p>"; p($z); $t0 = microtime(true); $arraysOf=array(); $inicio=memory_get_usage(); for ($i=0; $i<1000; $i++) { $z = new stdClass(); for ($j=0; $j<1000; $j++) { $z->aaa = 'aaa'; $z->bbb = 'bbb'; $z->ccc = $z->aaa.$z->bbb; } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>arrays: '.(microtime(true) - $t0)."</p>"; echo '<p>memory: '.($fin-$inicio)."</p>"; p($z); ?>
И я получил следующий результат:
arrays: 1.8451430797577 memory: 460416 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 1.8294548988342 memory: 275696 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 2.2577090263367 memory: 483648 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )
Заключение для php 5.4
ps: в качестве примечания, если класс определен, но члены тогда, использование этого класса происходит медленнее. Он также использует больше памяти. По-видимому, секрет состоит в том, чтобы определить членов
Я обновился с php 5.4 до php 5.5 (5.5.12 x86 windows).
arrays: 1.6465699672699 memory: 460400 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 1.8687851428986 memory: 363704 SplFixedArray Object ( [0] => aaa [1] => bbb [2] => aaabbb ) arrays: 1.8554251194 memory: 275568 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 2.0101680755615 memory: 483656 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )
Я использовал этот код для «профилирования» (1000 экземпляров, 1000 000 операций чтения / записи):
function p($i) { echo '<pre>'; print_r($i); echo '</pre>'; } $t0 = microtime(true); for ($i=0; $i<1000; $i++) { $z = array(); for ($j=0; $j<1000; $j++) { $z['aaa'] = 'aaa'; $z['bbb'] = 'bbb'; $z['ccc'] = $z['aaa'].$z['bbb']; } } echo '<p>arrays: '.(microtime(true) - $t0); p($z); $t0 = microtime(true); for ($i=0; $i<1000; $i++) { $z = (object) null; for ($j=0; $j<1000; $j++) { $z->aaa = 'aaa'; $z->bbb = 'bbb'; $z->ccc = $z->aaa.$z->bbb; } } echo '<p>obj: '.(microtime(true) - $t0); p($z); echo '<p> phpversion '.phpversion();
Он выводит на моем хостинге LINUX этот материал:
arrays: 1.1085488796234 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) obj: 1.2824709415436 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) phpversion 5.2.17
поэтому в заключении: объекты медленнее даже на PHP 5.2. Не используйте объекты, если вам действительно не нужны их функции oop.
Вы не указали нам код для того, как работает функция $object->value
, поскольку это может быть тот бэкэнд, который представляет собой массив, в котором теоретически использование массива будет быстрее, так как оно включает в себя еще один вызов функции. Стоимость выполнения поиска, вероятно, будет огромной по сравнению с вызовом функции. Если это переменная, будет очень мало различий, поскольку объекты и массивы на PHP имеют очень схожую реализацию.
Если вы ищете оптимизацию, вам потребуется профиль, чтобы проверить, где используется большая часть времени. Я подозреваю, что изменение объектов на массивы не будет иметь большого значения.
Вы всегда можете проверить PHP-исходный код для функций микро-производительности.
Но, на первый взгляд, никакое выполнение ['value'] не будет быстрее, потому что PHP должен выполнить поиск по тому, где найти ['value'], даже если вы хотите, чтобы хэш-таблица выглядела O (1), это не гарантировано. При использовании Text-index больше накладных расходов.
Если объект содержит только 1 переменную, к которой вам нужно получить доступ, то есть значение, при использовании объекта больше накладных расходов.
Я вижу, что это своего рода старый пост, поэтому я подумал, что я его обновлю. вот мои коды и статистика, сделанные на Zend CE 5.3.21. Я попытался проверить все это, сохранить информацию и потянуть ее обратно.
V1: занимает 0,83 с
for ($i=1; $i<1000000; $i++) { $a = get_one(); $b = $a[0]; $b = $a[1]; } function get_one() { return array(1,1); }
V2: занимает 3,05 сек
for ($i=1; $i<1000000; $i++) { $a = get_one(); $b = $a->v; $b = $a->k; } function get_one() { $ret = new test(); $ret->v = 1; $reb->k = 1; return $ret; } class test { public $v; public $k; }
V3: занимает 1,98 сек (обратите внимание, что конструктор улучшает производительность)
for ($i=1; $i<1000000; $i++) { $a = get_one(); $b = $a->v; $b = $a->k; } function get_one() { return new test(1,1); } class test { public $v; public $k; public function __construct($v, $k) { $this->v = $v; $this->k = $k; } }
Если массивы и классы имеют одинаковую производительность, я думаю, что использование объектов предопределенных классов для хранения / передачи бизнес-данных сделает нашу программу более логичной и более читаемой.
Сегодня, с современными идеями, такими как Eclipse, Netbean … очень удобно знать, какая информация объекты (предопределенного класса) несут, но массивы не так
Например: с массивом
function registerCourse(array $student) { // Right here I don't know how a $student look like unless doing a print_r() or var_dump() .... }
С объектом
class Studen { private $_name, $_age; public function getAge() {} public function getName() {} .. } function registerCourse(Studen $student) { // Right here I just Ctrl+Space $student or click "Student" and I know I can get name or age from it ... }
Я использую код magallanes под php 7.0.9:
arrays: 0.19802498817444 memory: 324672 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.18602299690247 memory: 132376 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.1950249671936 memory: 348296 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )
И пользователь php 7.1.3:
arrays: 0.59932994842529 memory: 444920 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.72895789146423 memory: 164512 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.61777496337891 memory: 484416 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )