Производительность массива PHP

Я тестирую алгоритм для упаковки 2d bin, и я выбрал PHP, чтобы издеваться над этим, так как сейчас это мой хлеб и масло.

Как вы можете видеть на http://themworks.com/pack_v0.2/oopack.php?ol=1, он работает очень хорошо, но вам нужно подождать около 10-20 секунд для 100 прямоугольников для упаковки. Для некоторых трудно обрабатываемых наборов он достигнет предела времени выполнения php 30s.

Я сделал некоторое профилирование, и это показывает, что большую часть времени мой скрипт проходит через разные части небольшого массива 2d с 0 и 1 в нем. Он либо проверяет, равна ли определенная ячейка 0/1, либо устанавливает значение 0/1. Он может выполнять такие операции в миллион раз и каждый раз требуется несколько микросекунд.

Думаю, я мог бы использовать массив логических элементов на статически типизированном языке, и все будет быстрее. Или даже сделать массив из 1 битовых значений. Я собираюсь преобразовать все это в компилируемый язык. Является ли PHP просто плохой?

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

Редактировать. Эта функция вызывается больше, чем любая другая. Он читает несколько свойств очень простого объекта и проходит через очень небольшую часть небольшого массива, чтобы проверить, есть ли какой-либо элемент, не равный 0.

function fits($bin, $w, $h, $x, $y) { $w += $x; $h += $y; for ($i = $x; $i < $w; $i++) { for ($j = $y; $j < $h; $j++) { if ($bin[$i][$j] !== 0) { return false; } } } return true; } 

Обновление: я попытался использовать 1d-массив вместо 2d в качестве одного из предложенных ответов. Поскольку мне всегда нужно иметь доступную ширину бина, я решил обернуть все в объект. Кроме того, теперь в каждом цикле индекс нужно вычислить. Теперь скрипту требуется еще больше времени для запуска. Другие методы не принесли большого повышения производительности, а сделали код менее читаемым. Думаю, время для хип-хопа.

Обновление: поскольку hiphop php работает только на linux, и у меня его нет, я решил переписать все на C ++. Приятно освежать старые навыки. Кроме того, если я найду способ использовать хип-хоп, будет интересно сравнить написанный вручную код на C ++ и создать один хип-хоп.

Обновление: я переписал эту вещь в c ++, в среднем она работает в 20 раз быстрее и использует гораздо меньше памяти. Позвольте мне посмотреть, могу ли я сделать это еще быстрее.

Доступ к массиву в PHP, безусловно, может быть медленным. PHP использует хеш-таблицы для реализации массивов, т. Е. Для доступа к элементу в массиве он должен вычислять хэш и перемещать связанный список. Использование скомпилированного языка с реальными массивами, безусловно, повысит производительность, потому что есть прямой доступ к памяти. Для интересующего: код для хэш-доступа со строкой и с целым числом .

Что касается вашего кода, есть несколько моментов, которые я бы оптимизировал:

  • return напрямую, не break дважды.
  • поместите $file->get_width() и $file->get_height в простые переменные. Я предполагаю, что высота или ширина не изменяются в течение всего процесса. Помните: функции в PHP медленны.
  • Используйте одномерный массив вместо вложенных массивов. Вы сохраняете один хэш-поиск на итерацию таким образом. На самом деле одномерный массив только немного быстрее или даже немного медленнее. Сравнение нескольких способов сохранения данных об эффективности и использовании памяти .

,

 function fits($bin, $x, $y, $w, $h) { $w += $x; $h += $y; for ($i = $x; $i < $w; ++$i) { for ($j = $y; $j < $h; ++$j) { if ($bin[$i][$j] !== 0) { return false; } } } return true; } 

Хотя я не уверен, почему вы добавляете $x к $width / $y к $height . Разве вы не хотите перебирать текущие координаты в границы изображений?

Решение вашей проблемы может быть https://github.com/facebook/hiphop-php/wiki/

Как сказал все остальные, PHP не является оптимальным языком для интенсивных вычислений. Он также не имеет тип массива. То, что описано как array() в PHP, действительно представляет собой словарь / хэш-карту. У него есть несколько оптимизаций для двойного списка, но, как вы уже обнаружили, он не обеспечивает такое же поведение во время выполнения, как C-указатели и массивы.

HipHop может преобразовать PHP-код в оптимизированный C ++. Он также был нацелен на манипуляции с строкой, но он вполне мог предложить правильное преобразование массива / списка.

Отказ от ответственности: я никогда не пробовал. Просто хотел внести свой интеллектуальный звуковой ответ.

Чтобы предложить другую альтернативу PHP:

Вы заглянули в SplFixedArray ?

В зависимости от того, как массивы структурированы (линейные от 0 до x), это может работать довольно быстро

Для сравнения см .: http://www.slideshare.net/tobias382/new-spl-features-in-php-53 Слайд 15 и 16 (извините, не нашел лучшего)

Более поздней альтернативой является расширение QB для PHP, специально разработанное для решения этой проблемы.

Хотя PHP – отличный язык для создания сложного веб-приложения, он накладывает определенные ограничения. Написание кода, выполняющего низкоуровневые, интенсивно вычислительные задачи в PHP, обычно непрактично – это просто слишком медленно. Расширение QB устраняет эту слабость PHP. Переведя коды кода Zend и выполнив их через статически типизированную виртуальную машину, QB предлагает прирост производительности по порядку величины. Добавленная мощность позволяет программистам PHP делать то, что они не могли сделать до этого, такое сложное манипулирование изображениями на уровне пикселей.

См .: http://php-qb.net/

Массивы в PHP действительно кажутся довольно медленными, особенно зацикливаясь на многомерных массивах. Другой вариант – попробовать Quercus . Это реализация PHP в Java. Я полагаю, он использует массивы Java. Однако я не сделал сравнения.

Вопрос почти поддается оценке, как «в основном основанный на мнениях». С этим в мыслях:

«Является ли PHP просто нехорошо?»

PHP изначально был просто языком веб-шаблонов, и простота была выше, чем производительность, когда она была разработана. Он со временем эволюционировал, и было добавлено много оптимизаций, но, тем не менее, производительность PHP относительно бедна для других платформ. Поэтому, если ваши критерии – это производительность, PHP не подходит для этого.

«Я собираюсь превратить все это в компилируемый язык».

Технически, PHP также может быть скомпилирован. Существует PHP-компилятор от C ++ от Facebook. У Zend есть справедливый вид компилятора. Раньше был PHP на интерпретаторе Java (хотя и не активен, если я правильно помню).

Я бы порекомендовал вам попробовать Java, потому что синтаксис подобен, в конце концов, это было одним из вдохновений PHP 5. Байт-код Java скомпилирован в собственный код с JDK 1.5. Производительность должна возникнуть примерно в 4 раза для той же структуры кода (при условии, что вы используете дистрибутив PHP сообщества).