PHP Objects vs Arrays - Сравнение производительности при итерации - PullRequest
82 голосов
/ 03 февраля 2010

У меня есть огромное количество объектов PHP для нейронной сети, для которых мне нужно перебрать и выполнить некоторые математические операции. Мне было интересно, если бы мне было лучше использовать ассоциативный массив над экземплярами классов?

Я имею дело примерно с 3640 объектами и повторяюсь около 1004 * раз (в лучшем случае), поэтому любая микрооптимизация очень помогает. Будет ли это неизбежно быстрее $object['value'], чем $object->value?

Редактировать: Так что они оба одинаковы. Но я предполагаю, что для конструктора будут небольшие накладные расходы? В любом случае, я не думаю, что хочу обменять свои прекрасные классы на грязные массивы: P

Ответы [ 8 ]

62 голосов
/ 02 июня 2014

Основываясь на коде Quazzle, я запустил следующий код (5.4.16 windows 64bits):

<code><?php
class SomeClass {
    public $aaa;
    public $bbb;
    public $ccc;
    }

function p($i) {
  echo '<pre>';
  print_r($i);
  echo '
'; } $ t0 = микротайм (правда); $ ArraysOf = массив (); $ Inicio = memory_get_usage (); для ($ i = 0; $ i <1000; $ i ++) { $ z = array (); для ($ j = 0; $ j <1000; $ j ++) { $ z ['aaa'] = 'aaa'; $ z ['bbb'] = 'bbb'; $ z ['ccc'] = $ z ['aaa']. $ z ['bbb']; } $ ArraysOf [] = $ г; } $ Плавника = memory_get_usage (); echo '<p> arrays:'. (microtime (true) - $ t0). ""; echo '

memory:'. ($ fin- $ inicio). "

"; р ($ г); $ t0 = микротайм (правда); $ ArraysOf = массив (); $ Inicio = memory_get_usage (); для ($ i = 0; $ i <1000; $ i ++) { $ z = новый SomeClass (); для ($ j = 0; $ j <1000; $ j ++) { $ z-> aaa = 'aaa'; $ z-> bbb = 'bbb'; $ z-> ccc = $ z-> aaa. $ z-> bbb; } $ ArraysOf [] = $ г; } $ Плавника = memory_get_usage (); echo '

arrays:'. (microtime (true) - $ t0). "

"; echo '

memory:'. ($ fin- $ inicio). "

"; р ($ г); $ t0 = микротайм (правда); $ ArraysOf = массив (); $ Inicio = memory_get_usage (); для ($ i = 0; $ i <1000; $ i ++) { $ z = новый stdClass (); для ($ j = 0; $ j <1000; $ j ++) { $ z-> aaa = 'aaa'; $ z-> bbb = 'bbb'; $ z-> ccc = $ z-> aaa. $ z-> bbb; } $ ArraysOf [] = $ г; } $ Плавника = memory_get_usage (); echo '

arrays:'. (microtime (true) - $ t0). "

"; echo '

memory:'. ($ fin- $ inicio). "

"; р ($ г); ?>

И я получил следующий результат:

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

  1. Класс быстрее, чем массивы (но незначительно).
  2. stdClass это зло.
  3. Класс использует меньше памяти, чем массивы. (примерно на 30-40% меньше !!)

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
)

Вывод по php 5.5

  1. Для массивов PHP 5.5 быстрее, чем PHP 5.4, для объектов это почти то же самое
  2. Класс работает медленнее, чем массивы, благодаря оптимизации PHP 5.5 и массивов.
  3. stdClass это зло.
  4. Класс по-прежнему использует меньше памяти, чем массивы. (примерно на 30-40% меньше !!).
  5. SplFixedArray аналогичен использованию класса, но использует больше памяти.
9 голосов
/ 08 декабря 2012

Я использовал этот код для «профилирования» (1000 экземпляров, 1000 000 операций чтения / записи):

<code>function p($i) {
  echo '<pre>';
  print_r($i);
  echo '
';} $ t0 = microtime (true);для ($ i = 0; $ i <1000; $ i ++) {$ z = array ();для ($ j = 0; $ j <1000; $ j ++) {$ z ['aaa'] = 'aaa';$ z ['bbb'] = 'bbb';$ z ['ccc'] = $ z ['aaa']. $ z ['bbb'];}} echo '<p> arrays:'. (microtime (true) - $ t0);р ($ г);$ t0 = микротайм (правда);для ($ i = 0; $ i <1000; $ i ++) {$ z = (объект) null;для ($ j = 0; $ j <1000; $ j ++) {$ z-> aaa = 'aaa';$ z-> bbb = 'bbb';$ z-> ccc = $ z-> aaa. $ z-> bbb;}} echo '

obj:'. (microtime (true) - $ t0);р ($ г);echo '

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.Не используйте объекты, если вам действительно не нужны их функции.

3 голосов
/ 23 июня 2017

Я использую код 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
)                      
2 голосов
/ 14 сентября 2013

Я вижу, что это своего рода старый пост, поэтому я решил обновить его. вот мои коды и статистика, сделанные на 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;
  }
}
2 голосов
/ 03 февраля 2010

Вы не показали нам код того, как работает $object->value, так как это может быть то, что бэкэнд это массив, в этом случае теоретически использование массива будет быстрее, поскольку в нем задействована одна функция вызов. Стоимость поиска, вероятно, будет огромной по сравнению с вызовом функции. Если это переменная, разница будет очень незначительной, поскольку объекты и массивы в PHP имеют очень похожую реализацию.

Если вы смотрите на оптимизацию, вам нужно будет профилировать, чтобы проверить, где большую часть времени используется. Я подозреваю, что замена объектов на массивы не будет иметь большого значения.

1 голос
/ 03 февраля 2010

Вы всегда можете проверить исходный код PHP на наличие таких микропроцессорных функций.

Но, на первый взгляд, выполнение ['value'] не будет быстрее, потому что PHP должен выполнить поиск, чтобы найти ['value'], даже если поиск по хеш-таблице должен быть O (1), это гарантировано. При использовании Text-index возникают дополнительные издержки.

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

0 голосов
/ 05 июня 2019

скрипт magallanes @ PHP 7.3.5

  • SomeClass Object самый быстрый и легкий.
  • Array 1,32x скорость. 2,70x память.
  • 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
)
0 голосов
/ 19 марта 2015

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

Сегодня, с такими современными идеями, как 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
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...