PHP Objects vs Arrays - Сравнение производительности при итерации
У меня есть огромное количество объектов PHP для нейронной сети, для которой я должен перебирать и выполнять некоторые математические операции. Мне было интересно, не лучше ли мне использовать ассоциативный массив над экземплярами классов?
Я имею дело с объектами 3640
и итерацией вокруг 500
раз (в лучшем случае) поверх этого, поэтому любая микро-оптимизация очень помогает. Было бы неизбежно быстрее $object['value']
сделать $object->value
?
Изменить:. Они одинаковы. Но я думаю, что для конструктора будет немного накладных расходов? В любом случае, я не думаю, что хочу обменять мои красивые классы на грязные массивы: P
Ответы
Ответ 1
Основанный на коде 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
- Класс - это посты, чем массивы (но незначительно).
- stdClass является злым.
- Класс использует меньше памяти, чем массивы. (примерно на 30-40% меньше!!)
ps: как примечание, если класс определен, но члены тогда, использование этого класса медленнее. Он также использует больше памяти. Очевидно, секрет заключается в определении членов
Update
Я обновил с 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
)
Заключение для php 5.5
- Для массивов PHP 5.5 быстрее PHP 5.4, для объекта он почти такой же
- Класс медленнее, чем массивы, благодаря оптимизации PHP 5.5 и массивов.
- stdClass является злым.
- Класс по-прежнему использует меньше памяти, чем массивы. (на 30-40% меньше!!).
- SplFixedArray похож на использование класса, но он использует больше памяти.
Ответ 2
Я использовал этот код для "профилирования" (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.
Ответ 3
Я использую код 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
)
Ответ 4
Вы не показали нам код для того, как работает $object->value
, так как это может быть тот бэкэнд, это массив, в котором теоретически использование массива будет быстрее, так как оно включает в себя еще один вызов функции. Стоимость выполнения поиска, вероятно, будет огромной по сравнению с вызовом функции. Если это переменная, будет очень мало различий, поскольку объекты и массивы в PHP имеют очень похожую реализацию.
Если вы ищете оптимизацию, вам потребуется профиль, чтобы проверить, где используется большая часть времени. Я подозреваю, что изменение объектов на массивы не будет иметь большого значения.
Ответ 5
Я вижу, что это своего рода старое сообщение, поэтому я решил обновить его.
вот мои коды и статистика, сделанные на 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;
}
}
Ответ 6
Вы всегда можете проверить PHP-исходный код для функций микро-производительности.
Но на первый взгляд, не делать ['значение'] не будет быстрее, потому что PHP должен выполнить поиск по тому, где найти ['значение'], даже если вы хотите, чтобы поиск в хэш-таблице был O (1), это не гарантировано. Там, где вы используете Text-index, больше накладных расходов.
Если объект содержит только 1 переменную, к которой вам нужен доступ, то есть значение, при использовании объекта больше накладных расходов.
Ответ 7
Если массивы и классы имеют одинаковую производительность, я думаю, что использование объектов предопределенных классов для хранения/передачи бизнес-данных сделает нашу программу более логичной и более читаемой.
Сегодня, с современными идеями, такими как 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
...
}
Ответ 8
скрипт magallanes @PHP 7.3.5
-
SomeClass Object
является самым быстрым и легким. -
Array
1.32x скорость. 2.70х памяти. -
stdClass Object
1.65x скорость. 2.94x памяти.
Необработанная продукция:
arrays: 0.064794063568115
memory: 444920
Array (
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
arrays: 0.048975944519043
memory: 164512
SomeClass Object (
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
arrays: 0.081161022186279
memory: 484416
stdClass Object (
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)