Огромное снижение производительности при доступе к объекту в ассоциативном массиве PHP - PullRequest
6 голосов
/ 16 декабря 2009

Я наблюдаю огромное снижение производительности PHP-скрипта (из командной строки), вызванное простым заданием (время выполнения увеличилось с 0,8 ~ 0,9 секунды до 29.x секунд).

Скрипт сначала получает много данных из базы данных MySQL и создает объекты различных пользовательских классов. После этой выборки (теперь php использует около 500 МБ ОЗУ), я зацикливаю массив из примерно 3'500 Sample объектов, каждый из которых имеет ассоциативный массив (размер около 100 записей) в качестве одного из своих свойств. Этот массив содержит Value объекты, которые являются небольшими объектами с двумя свойствами, а ключи являются целыми числами, меньшими, чем 6'000. Вот где я наткнулся на проблему, см. Этот код:

foreach ($samples as $id => $s) {    # $s is now a 'Sample' object
    $values = $s->values();          # $values is an array of 'Value' objects

    if (isset($values[$match_id])) {
        $num_tested++;
        # $val = $values[$match_id];     # contains a 'Value' object
        # $val = &$values[...]; -> the loop never ends (!)
    }
}

Обратите внимание, что закомментированная строка. Если я запускаю код, как он отображается здесь, этот блок будет работать от 0,8 до 0,9 секунд . Если я раскомментирую эту единственную строку, блок будет работать в течение почти 30 секунд . Я обнаружил, что если массив неассоциативен (он содержит только последовательные ключи от 0 до 100), время выполнения увеличивается только до 1,8 ~ 1,9 секунды.
Кажется, это происходит из-за непоследовательных ключей массива, которые я использую, но опять же, почему производительность еще не снижается при вызове isset($values[$match_id])? Есть ли обходной путь для этого или я должен жить с этим?

Запуск PHP 5.3.0, Zend Engine v2.3.0, Mac OS X Server 10.6.2

Ответы [ 2 ]

3 голосов
/ 16 декабря 2009

Если вы используете 5.3, посмотрите на новые структуры данных Spl. Они могут значительно увеличить производительность для больших коллекций, как показано здесь и здесь . Кроме того, довольно сложно сказать, что может быть причиной проблемы. Вы пытались использовать xdebug или Zend_Debugger для получения более подробной информации?

1 голос
/ 16 декабря 2009

Попробуйте заменить $val = $values[$match_id] (назначение копией) на $val =& $values[$match_id] (назначение по ссылке) и посмотрите, работает ли он лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...