Что делать, если скрипт съедает 50Гб памяти?

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

В моём текущем проекте есть Customers, у которых есть много Orders. Надо эти Orders обработать и вывести обработанную информацию.

PHP:
  1. foreach ($customers as &$customer) {
  2.     $id = $customer['Customer']['id'];
  3.    
  4.     $orders = $this->processOrders($id); // eats a lot of memory
  5.     $customer['Order'] = $orders;
  6. }
  7.  
  8. $this->set(compact('customers'));

Но функция processOrders($customerId) работает как-то странно, при каждом новом вызове съедая 100Мб памяти. И после 40 клиентов заканчивается физическая память и начинается жуткий своп.

Программист-идеалист разбирался бы в этой странной функции долго и нудно, смотрел, где утечка памяти, оптимизировал алгоритм. Я посмотрел мельком на эту функцию, понял, что на её понимание может уйти несколько часов. Потом заметил, что для каждого клиента обработка заказов происходит только один раз и можно просто разбить работу скрипта на части. Пусть скрипт обрабатывает 10 клиентов (съедая всего 1Гб памяти), а потом перезапускается.

PHP:
  1. $counter = 0;
  2. foreach ($customers as $customer) {
  3.     $id = $customer['Customer']['id'];
  4.    
  5.     if (Cache::read('Customer.Order.'.$id)==false) {
  6.         $orders = $this->processOrders($id); // eats a lot of memory
  7.         Cache::write('Customer.Order.'.$id, $orders);
  8.         if (++$counter>=10) {
  9.             exit('refreshing...<script>window.location.reload(true)</script>');
  10.         }
  11.     }
  12. }
  13.  
  14. foreach ($customers as &$customer) {
  15.     $id = $customer['Customer']['id'];
  16.     $customer['Order'] = Cache::read('Customer.Order.'.$id);
  17. }
  18.  
  19. $this->set(compact('customers'));

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

Спасибо CakePHP Cache и JavaScript.


Понравилось?

  1. Подпишись через RSS
  2. Расскажи о http://php.southpark.com.ua друзьям.
    Все способы хороши: ICQ, E-mail, свой блог, комментарий в чужом блоге или сообщение на форуме
  3. Добавь статью на news2.ru, Хабрахабр или в закладки

Огромное спасибо!

И не стесняйтесь комментировать - у меня стоит плагин, который убирает rel="nofollow" у людей, которые написали больше 5 комментариев.

RSS feed | Trackback URI

23 комментария »

Comment by quard
2008-03-17 17:56:01

А какой кешевый движок используешь?

И получается что когда ты страничку перезагружаешь, ты заново проходишь по списку, но обрабатываешь клиента если он не обработан? может лучше передавать параметр где хранится последний обработанный клиент?

2008-03-18 14:21:02

можно, но так быстрее (для меня, а не компьютера) и надёжнее (вдруг в процессе ещё клиенты добавятся)

 
 
Comment by empty
2008-03-17 18:36:15

Можно и так.
заметил там window.location.reload(true)
если доработать дальше, то всё это можно сделать "красивенько" добавив немного ajax и эффектов(по желанию)
Второй foreach, думаю, можно убрать

PS хотя всёравно както ужасно смотрится, мне кажется что струтура полученных данных не оптимальн, но это имхо.

2008-03-18 14:25:40

угу, в location.reload вся соль. true указывает браузеру, что страницу не надо брать из кеша.

весь код исполняется 5 минут, просто памяти много съедает. вдобавок непонятно, надо будет ли вообще хотя бы ещё раз исполнять код. поэтому спецэффекты ни к чему как и оптимизация именно этого куска кода.

 
 
2008-03-17 22:43:50

Это задача не для пхп (точней не тот пхп который показывает странички)!

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

 
2008-03-17 23:05:56

жудкий -> жуткий

2008-03-18 14:28:00

спасибо, исправил

 
 
Comment by Vladimir Rusinov Subscribed to comments via email
2008-03-17 23:20:09

я как сисадмин за такое руки бы поотрывал. :)

2008-03-18 15:01:47

я бы как технический директор за это уволил :grin:
на своём компьютере что хочу, то и делаю. конечно, на живом сервере такого делать нельзя.

 
 
Comment by saygon Subscribed to comments via email
2008-03-18 01:20:39

Зачем в первом варианте было множить контейнер?
$orders = $this->processOrders($id); // eats a lot of memory
$customer['Order'] = $orders;

так не проще и по затратам памяти легче? :)
$customer['Order'] = $this->processOrders($id);

2008-03-18 15:06:51

чтобы на 1024х768 код с комментариями не вылезал за пределы экрана :smile:

Comment by Виктор Subscribed to comments via email
2008-03-20 17:24:20

Вова, а какой редактор используешь? Просто интересно. :-)

(Comments wont nest below this level)
2008-03-20 17:48:50

Я пользуюсь сразу тремя редакторами:
1. Мелочь поправить - Notepad++
2. На хороших компьютерах: Zend IDE + их же дебаг
3. На ноутбуках: Komodo + XDebug

Если основной язык не PHP, а HTML+CSS+JS, то хорошие Dreamweaver и Aptana. Через год, возможно, будет нормальной PDT на Eclipse или Zend на Eclipse.

Для блога - Notepad++ или Word.

Comment by Виктор Subscribed to comments via email
2008-03-20 18:09:13

Спасибо за ответ. Я хотя бы узнал на чем пишут тру программисты. :wink:

 
 
 
 
 
2008-03-18 14:56:16

[...] Что делать, если скрипт съедает 50Гб памяти? [...]

 
2008-03-18 16:35:52

[...] Что делать, если скрипт съедает 50Гб памяти? [...]

 
2008-03-21 11:51:49

Простите за оффтопик, нигде не могу найти ваш контактный почтовый адрес.
Вы можете со мной связаться? Разговор касается сотрудничества.
С уважением.

2008-03-21 12:05:30

отписался на почту

 
 
Comment by Iv Subscribed to comments via email
2008-03-25 10:20:43

Тоже простите за оффтопик,
интересно, как реализуете на cakePHP многоязычность сайта?

IСQ 345560714

 
Comment by Борис Subscribed to comments via email
2008-04-24 13:42:28

И уж я за одно, простите поофтопю. Владимир, может действительно контактный формялр чтоли сделаете :)

Ищем специалиста по кейку для реализации нового проекта в германии. Владимир, будем рады вашему интересу.

jinis_services yahoo de

 
Comment by Михаил
2008-06-06 11:46:48

Интересная статья, спасибо, много полезного узнал, в т.ч. и в коментах)

 
Comment by Скорпион
2008-06-24 10:13:38

Ни фига себе скриптик, 50 ГБ памяти - это где хоть столько можно взять? Я 4 максимум видел!?!

 
Comment by bananos Subscribed to comments via email
2008-08-13 00:29:28

Плохое решение.
Пахнет подпорками и кривостью при первом же взгляде.
Ситуативное решение которое в будущем вылезет в очередной фикс

 
Имя (required)
E-mail (required - never shown publicly)
URL
Текст комментария
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> in your comment.