Есть вопрос... можно ли в PHP как-то управлять содержимым переменных(массивов etc) в памяти? Задача, на самом деле проста - сохранять и восстанавливать значения переменных путем копирования кусков памяти, не применяя накладную сериализацию.
MiksIr Быстрее сериализации вы это не сделаете. Сериализация - это то же самое сохранение и восстановление структур в памяти. Парсинг там очень простой, работает она быстро, т.к. нативные функции. Если скорость сериализации не устраивает - значит почти наверняка где-то ошибка в проектировании приложения.
Ti, т.е. то, что в Си очевидно, в ПХП "не должны хотеть"? Тут недавно тема была, когда на ПХП мультиплексирующий сервер делали - это "можно хотеть?" =) Dagdamor, все относительно То, что для кого-то - нормальная скорость, для меня смерти подобно. А задача то проста - кеширование данных в мемкеше и варианта два - или разбиение структуры данных на множество мелких, что не всегда приемлемо, или прямая работа с памятью. Последнее удобно, если не бояться этого, и быстрее однозначно, ибо копирование блоков памяти все же быстрее, чем анализ структуры и кодирование этой структуры.
Если бы была возможность увеличить во-первых время разработки в несколько раз, и во-вторых увеличить число программистов (кстати, более дорогих) раза в два, то так и поступил бы. Пока, же приходится на PHP. В общем, рано или поздно, дойдут руки реализовать расширение для php, которое будет гонять данные в мемкеш без затрат на сериализацию, но может есть уже решения - вот и интересуюсь.
MiksIr Я про такие не слышал. Дело в том, что структура в памяти - это структура в памяти, ее же нельзя так просто скопировать (грубо говоря, она рассована в физической памяти по разным блокам). Т.е. ее надо анализировать, преобразовывать... только потом копировать. Предрекаю, что когда вы напишете это нативное расширение для PHP, оно будет работать со скоростью serialize.
Dagdamor, возможно, не знаю принципов хранения данных в пхп. По-этому и спросил, может кто знает. Поверьте, вопрос конкретный, из разряда "я знаю, что спрашиваю", так что указания обходных путей не требуется. 440Hz, в PHP с моей точки зрения очень много того, что там не надо. Так что, что нужно, а что нет - субъективная оценка из задач проекта. А я думаю о том, что PHP: $t1 = microtime(true); $a = 5; for ($i=0; $i<10000; $i++) { $b = $a; } echo (microtime(true)-$t1)."\n"; 0.00281000137329 PHP: $t1 = microtime(true); $a = 5; for ($i=0; $i<10000; $i++) { $b = unserialize(serialize($a)); } echo (microtime(true)-$t1)."\n"; 0.0510120391846
Для кого-то 0.05, а для кого-то в 20(!) раз Оптимизируем везде. Я лучше потеряю в скорости из-за увеличения абстракции там, где это нужно, чем на дурацкой сериализации В общем, я понял, что решения нет, спасибо Будем искать
узкое место в 99% скриптов - SQL запросы... А для чего, как вы думаете, мне нужен мемкеш? Но вот когда получение данных из мемкеша из-за сериализации занимает больше времени, чем соответствующий запрос в базу... вот тут начинаешь задумываться. С одной стороны можно плюнуть, ибо все ж задача мемкеша не ускорить работу, а разгрузить базу... с другой стороны, не красиво сие
интересная ситуация. при случае отпишитесь поподробнее? хотя я просто плюю если скрипт укладываетс в 0.5-1 сек. а на какой системе все крутиться? под каким софтом?
Да нормальная ситуация, если база не нагружена и объем данных более-менее приличный. И конфигурация системы тут ничего не даст - изменятся абсолютные величины, но не относительные. Тем более, что в случае с кешированием данных, все же напрашивается решение не кешировать запросы as-is, а кешировать результирующие структуры, полученные уже путем анализа данных из базы. А там структуры посложнее бывают, чем массив массивов. Да, можно поднимать частоты процессоров на бекендах, только стараешься все же найти баланс между затратами на оптимизацию и затратами на железо. Возможно, в данном случае и перебор, но если бы было бы готовое решение без сериализации - то "почему бы и нет". Слова про то, что "не ПХП это дело"... ну несерьезные это ответы - сискалы в ядро - ПХП-шное дело, а работа с памятью - нет Не логично А 0.5 секунд на запрос пользователя в нашем случае непозволительная роскошь ;(
Уважаемый, да не в обиду сказанно, да и впринципе это не лично вам, а вообще общее наблюдение. Дело не в том, что PHP медленен, дело в: а) Нехватки знаний б) Лени думать в) Недостаточности воображения г) Нежелания пробовать, потому что "Я СКАЗАЛ ЭТО ПЛОХО!". В общем то я часто с таким сталкиваюсь, но т.к. я упрямый очень в этом плане, я в офисе главного программера пробиваю через эти 4 пункта переодически - то он считает глупой мыслью, то думает будет медленно, то ещё "напишем демон" (тока на это уйдёт пара месяцев, а база уже еле справляеться) и.т.д. Пробивал (я много работаю с memcache между прочим) эту упрямость, и ниразу ещё не ошибся - 3 из 3-х моих серьёзных оптимизаций прекрасно работают и сильно снизили нагрузку на базу данных. А вот теперь лично к вам: Вы зря думаете что memcache это плохое решение.. Не, конечно, если вы планируете иметь до 50-60 тысячь человек online, то вам нужен C/C++ демон, распределение между серверами и.т.д., но не думаю что у вас сейчас такая задача. 1) Memcache API сам сериализует и десериализует данные, вам самому это делать НЕ НАДО. 2). На P4 2.4 GHz процессоре по TCP/IP на localhost PHP выполнял у меня 20 000 set или get'ов, если по сети, будет немного меньше. Факт в том, что это был даже не сервер, обычный Desktop комп, который мы используем как DEV сервер. Тобишь цикл в 20 000 set'ов и потом 20 000 get'ов выполнялся за 2 секунды. Даже с учётом сериализации это очень быстро. А ведь memcache может хранить не только переменные/масивы, но и объекты. 3) Если у вас не стоит задачи, обращаться к кеширующему серверу по сети, тоесть он будет работать на том же компе что и PHP, то используйте APC или XCache (очень рекомендую, он ещё в добавок работает как кешер PHP байткода, даёт очень большой прирост в скорости работы PHP скриптов) - они всё держут в Shared memory, это и есть ваша присловутая прямая работа с памятью. А вообще, если вам нужен сетевой кеширующий сервер, как вы собираетесь передавать данные от сервера к серверу? Как потом расшифровывать а какие же данные там пришли от кеширующего сервера? Так что вам в любом случае придёться приходить к собственной сериализации, писать свой протокол... Так что это равносильно изобретению велосипеда. Ну а если вы локально только работаете, есть готовые и быстрые решения, описанные выше.
Гм... а кто сказал, что мемкеш - плохое решение? И, кстати, откуда вы взяли, что (де)сериализация - это работа мемкеш библиотек? Сериализация осуществляется средствами PHP (стандартным внутренним вызовом serialize), а суть моего вопроса была - можно ли загонять в мемкеш данные AS IS они в памяти, без сериализации. Да, я соглашусь что сериализация не есть именно то узкое место, в которое все упрется, и не есть та задача, на которую стоит бросить силы всех разработчиков мгновенно, но если есть готовые решения, которые помогут выгадать пару-тройку миллисекунд - то почему бы и нет. APC, кстати, для сохранения структур использует ту же сериализацию... ну в общем, я к тому, что "я в курсе"
MiksIr, пытаться скопировать кусок памяти в котором ПХП хранит переменную бессмысленно. Там много служебного мусора. Все переменные ПХП хранятся с помощью одной универсальной структуры (zval-контейнер), которая содержит несколько служебных полей, объединение для хранения простых данных и указатель на сложные данные. В случае простых типов (число, знак, число с плавающей точкой), все данные хранятся в этой структуре, а в случае строк, массивов и объектов в структуре хранится указатель на кусок памяти, где лежит строка или на хэш таблицу, в которой хранится массив (объект), именно из-за этого даже переменные простых типов занимают в ПХП относительно много памяти. Думаю уже понятно, что пытаться копировать кусок памяти бессмысленно со всех точек зрения. Даже если скопировать всё что нужно, этот кусок памяти либо придётся распарсить для извлечения полезных данных, либо сохранить его полностью, а затем,,, (а что делать с этим куском мусора я и не знаю -).
dark-demon, ну не громадные, но вон, сериализация простого инта уже в 10 раз медленнее копирования работает. Vladson, вот только один минус - не мультисерверный ONK, ну я предполагал что-то вроде выделения памяти, обратного копирования туда этого куска и установки указателей на него. Спасибо за развернутый ответ
MiksIr, теоретически это наверно возможно, но для этого надо хорошо знать весь Zend Engine, чтобы правильно зарегистрировать всё что нужно и везде где надо.