Подтвердить что ты не робот

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

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

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

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

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

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

Изменить. Эта функция вызывается больше, чем любая другая. Он читает несколько свойств очень простого объекта и проходит через очень небольшую часть небольшого массива, чтобы проверить, есть ли какой-либо элемент, не равный 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 в качестве одного из предложенных ответов. Поскольку мне всегда нужно иметь доступную ширину бина, я решил обернуть все в объект. Кроме того, теперь в каждом цикле индекс нужно вычислить. Теперь для script требуется еще больше времени для запуска. Другие методы не принесли большого повышения производительности, а сделали код менее читаемым. Думаю, время для хип-хопа.

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

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

4b9b3361

Ответ 1

Доступ к массиву в 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. Вы не хотите перебирать текущие координаты к границам изображения?

Ответ 2

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

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

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

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

Ответ 3

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

Вы просмотрели SplFixedArray?

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

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

Ответ 4

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

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

Смотрите: http://php-qb.net/

Ответ 5

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

Ответ 6

Вопрос почти поддается определению, как "в основном основанный на мнениях". Имея это в виду:

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

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

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

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

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