PHP Loop Оптимизация производительности - PullRequest
2 голосов
/ 17 декабря 2009

Я пишу функцию PHP, которая должна будет циклически перемещаться по массиву указателей и для каждого элемента извлекать эти данные (будь то из базы данных MySQL или плоского файла). Есть ли у кого-нибудь идеи по оптимизации этого, поскольку потенциально могут быть тысячи и тысячи итераций?

Моей первой идеей было создание статического массива кэшированных данных, над которым я работаю, и любые изменения просто изменят этот кэшированный массив, после чего в конце я смогу записать его на диск. Однако в цикле из более 1000 элементов это было бы бесполезно, если бы я оставил в массиве только около 30 элементов. Каждый элемент не слишком большой, но 1000+ из них в памяти - это слишком много, следовательно, требуется дисковое хранилище.

Данные представляют собой только что сжатые сериализованные объекты. В настоящее время я использую базу данных для хранения данных, но я думаю, что, возможно, плоские файлы будут быстрее (меня не волнуют проблемы параллелизма, и мне не нужно разбирать их, просто разархивировать и десериализировать) У меня уже есть собственный итератор, который будет извлекать по 5 элементов за раз (чтобы сократить количество подключений к БД) и сохранять их в этом кэше. Но опять же, использование кеша, равного 30, когда мне нужно итерировать более тысячи, совершенно бесполезно.

По сути, мне просто нужен способ быстро перебрать все эти элементы.

Ответы [ 4 ]

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

Ну, вы не дали много, чтобы продолжить. Вы не описываете свои данные, и вы не описываете, что делают ваши данные или когда вам нужен один объект в отличие от другого, и как эти объекты временно освобождаются, и при каких обстоятельствах вы нуждаетесь в них обратно, и ... .

Так что все, что кто-нибудь здесь скажет, будет полным выстрелом в темноте.

... так вот, вот выстрел в темноте.

Если вам удобно одновременно хранить x элементов в памяти, выделите место для x элементов. Затем, каждый раз, когда вы получаете доступ к объекту, запишите время (это может означать не столько часы, сколько порядок их доступа). Сохраняйте каждый элемент в списке (он может быть реализован не в виде списка, а скорее как куча-подобная структура), чтобы последние использованные элементы появлялись в списке раньше. Когда вам нужно поместить новый в память, вы заменяете тот, который использовался давным-давно, а затем перемещаете этот элемент в начало списка. Вам может понадобиться сохранить другой индекс предметов, чтобы вы знали, где именно они находятся в списке, когда они вам нужны. Затем вы посмотрите, где находится элемент, свяжите его родительский и дочерний указатели, а затем переместите его в начало списка. Возможно, есть и другие способы оптимизации времени поиска.

Это называется LRU algroithm. Это схема замены страницы для виртуальной памяти. Что он делает, так это задерживает ваше узкое место (дисковый ввод / вывод) до тех пор, пока его, вероятно, невозможно избежать. Стоит отметить, что этот алгоритм не гарантирует оптимальной замены, но, тем не менее, работает довольно хорошо.

Кроме того, я бы рекомендовал распараллеливать ваш код в значительной степени (если это возможно), чтобы при загрузке или выгрузке одного элемента можно было загружать процессор, выполняя реальную работу.

Исходя из вашего комментария, вы работаете в нейронной сети. В случае вашего первоначального сложения данных (до этапа исправления) или когда вы активно используете его для классификации, я не вижу, как алгоритм является плохой идеей, если только нет никакого возможного способа соответствовать наиболее часто используемые узлы в памяти.

На этапе коррекции (возможно, обратно-подпорка?) Должно быть очевидно, какие узлы вы ДОЛЖНЫ хранить в памяти ... потому что вы уже посетили их!

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

0 голосов
/ 17 декабря 2009

Вы можете использовать memcached для хранения объектов при первом чтении, а затем использовать кэшированную версию в последующих вызовах. Memcached использует оперативную память для хранения объектов, поэтому, пока у вас достаточно памяти, вы получите большое ускорение. Есть php api к memcached

0 голосов
/ 17 декабря 2009

вы всегда можете выйти из цикла после получения необходимых данных. так что это не будет продолжать цикл. если это простой файл, который вы храните ... ваш серверный жесткий диск будет страдать, содержащий тысячи или миллионы файлов с разным размером файла. Но если вы говорите обо всем фактическом файле, хранящемся в БД. тогда гораздо лучше сохранить его в папке и просто сохранить путь к этому файлу в БД. И попробуйте поместить вытащенные элементы в XML. так что к нему гораздо проще получить доступ, и он может содержать много атрибутов для деталей извлекаемого элемента, например (имя, дата загрузки и т. д.)

0 голосов
/ 17 декабря 2009

Очевидно, что хранить его в памяти быстрее, чем что-либо еще. Насколько велика каждая вещь? Даже если они по 1 КБ, десять тысяч из них - это всего 10 млн.

...