нареканий нет. Просто всё что в PECL и ставить проще и не подводило оно никогда. Да и попадает оно туда не просто так. Тем не менее я не в курсе есть ли у xdebug профилер или нет.
попробовал и ваш пример. Получилось в 3 раза. Ладно победили. array_walk аутсайдер, хоть и удобен в некоторых случаях (не меняет курсор в массиве и тп). Тем не менее многие другие функции array_* в пхп вообще сложновато без сноровки реализовать foreach-ем. Сортировку, например.
эээ.. потоки php как раз умеет. И красным цветом я говорил про потоки но уж никак не про процессы. И балансировать нагрузку надо не такими вещами, а чем-то более гибким ;)
О том как добится чтобы пхп запускал потоки - см. bin-environment в предоставленном мной конфиге. И 128 потоков PHP - я забыл упомянуть - это для 8-ядерного сервера хорошо... =) Другими словами прочитав статью головой-то все равно думать надо. Это не HowTo.
не вариант. Время тратится не на парсинг строчки require в файле, а на заглядывание в файловую систему, просмотр mtime файла и тп. Поэкспериментируйте =).
хм.. затраты на созднание потока гораздо выше чем на его поддержку. Особенно учитывая то что при инициализации юзера отрабатывает некоторое количество бизнес-логики, что уже совсем намного более ресурсоемко чем голая работа с потоками. При этом все Anonymous-запросы отдельного потока, конечно, не требуют.
Сложно забыть, что http это stateless протокол ;). Тем не менее есть а) keepalive и b) - кто мешает рассматривать запрос (в частности, куки) в момент парсинга запроса? Висит, например, поток юзера где-то и приходит запрос который каким-либо образом считается именно запросом _данного_ пользователя. И переправляется потоку. Потоки убивать как сессии - 20 мин неактивности. Я уже использовал такую схему и результат настолько замечателен как я его и расписал ;).
Очень важный момент - ?> - действительно лучше не использовать в конце файла. Толку от неё - ноль.
echo 'asd' . 'dsa' против echo 'asd', 'dsa' толком никакой разницы не несут. Равно как и echo 'asd' против echo "asd". Выбирать что использовать лучше из общепринятых стандартов - двойные кавычки ТОЛЬКО когда в этом есть смысл (т.е. нужен парсинг переменных внутри и тп). И echo 'asd' . 'dsa' вместо конкантенации параметров запятой. Причём по скорости разницы можно сказать что вообще нет. Задумываться об этом глупо потому что в любой PHP-программе есть 99.99% мест заслуживающих большего внимания ;).
echo или print.. print используется теми кто к нему привык - т.е. пересаживается с Си, например. В php-мире превалирует-таки echo. Это факт.
OpenMP давно уже позволяет автоматом творить всё в потоках путём меток а-ля "вот тут можно многопоточно", "а тут многопоточно нельзя". Он не столь идеален как ручной способ но куда более быстрый в осуществлении.
diablitozz, проблемы многопоточности как явления нету, конечно. Есть проблема что программы создавать с поддержкой многопоточности не в пример сложнее чем линейные. И даже дело не в самом написании, а в проблемах которые возникают потом абсолютно внезапно в каком-то одном конкретном случае. Проблема может и через год возникнуть.
Кстати говоря забавно. Попробовал потоки в питоне на 8-ядерном сервере. Удалось выжать максимум 250% из 800%. В то время как на си с pthreads четко 800% при 8 потоках :)). Ещё интересно что в питоне (да будь проклят этот gil) потоки переключаются сначала операционкой, потом ещё и самим питоном... а в си - при создании потока он буквально "вешается" на 1 ядро.т.е. 7 потоков там сжирают ровно 7 ядер из 8, одно пустует (естественно, они меняются), а в питоне получается что все ядра пыхтят но не на полную катушку.
вы знаете сколько тактов CPU уходит на lock? На саму по себе операцию? Ожидание - да. Но это в тысячи раз быстрее чем традиционный метод PHP-программистов - счетчик в бд/файле.
А теперь представьте веб-приложение качественно нового уровня. Заходит юзер. Авторизуется. Какой-то поток берёт данные из бд. И таких юзеров в какой-то времени, допустим, тысяча. А теперь представьте что один юзер из авторизованных пишет сообщение другому. Традиционный вариант - каждый раз смотреть где-либо (в бд, скажем) есть новые сообщения или нет. А тут один поток просто говорит другому, мол "нью мессадж". И всё.
Конечно, всё не так просто. Конечно, это потом достаточно проблематично распределить на более чем 1 сервер. Но event-driven программирование явно шустрая штука.
Локи локами, но тут уже гораздо большее влияние на производительность оказыывает программист и архитектура приложения в целом.
В теории 4 ядра по 2 ггц будут явно медленнее одного на 8 (ограничения хотя бы на дублирующиеся кеши процессора). Однако 8ггц процессор будет в несколько дороже чем 4 ядра 2ггц.
Отсюда вывод что в теории создавать оооочень большое количество ядер - будет дешевле.
Предположим сервер. Например с 2 ядрами. Сейчас большинство PHP (например) программистов легко могут их занять. А теперь представьте сервер с 128 ядрами (а ведь будут массово). Чтобы эффективно их все использовать и не тратить до 30% времени на всякую чепуху (парсинг require в том же пхп) нужно использовать распределённую память и проч. Думаю огромный процент программистов высокоуровневых языков явно охренеет когда первый раз словит race condition. Начнёт читать про семафоры и подумает - что программист он не ахти какой оказывается.
А как заюзать многопоточность в высокоуровневых языках? PHP - вариант только с колво_ядер+1 поток при fastcgi + такое же кол-во потоков управляющего веб-сервера. Ну либо огромная куча форков апача с PHP как модулем (причём затраты на создание форка - кака). И каждый чертов PHP будет делать сотни две stat вызовов в фс, даже если стоит APC при каждом запросе.. (типичная ситуация для пользователей фреймворков а-ля ZendFramework). Уже абсурд. Питон. Есть потоки, после загрузки в основном только бизнес-логика работает. Но есть чёртов Global Interpreter Lock, который не позволяет-таки эффективно грузить много ядер (ну +20-30% будет максимум). Опять же питон придётся форкать. Появятся сложности с распределённой памятью (либо необходимый размер ОЗУ для работы вырастет в количестве форков, либо нужно добавлять ещё один хрупкий (при недостаточной сообразительности программиста) элемент такой как - отдельный распределённый кеш (который может создать массу race condition сложно уловимых). Как вариант - си с pthreads в который засовывать питон. Но это требует уже оочень высокой квалификации иначе есть угроза отстутствия прироста скорости вообще :).
Помимо всего прочего современный разработчик обязан делать софт не только многопоточным, но ещё и с возможонстью кластеризации. Два сервера с 4 ядрами явно лучше чем 1 с восемью.
Разрабатывать такие приложения очень сложно. Как правило требуется тратить огромное количество усилий на документирование и ТЗ иначе следующий или просто новый программист ничего не сможет понять.
Отчасти это причина почему у Java программистов обычно зарплата качественно выше чем PHP и находится на уровне Python/C.
Остаётся конечно возможность реализации совсем сложных решений - kernel-space многопоточников распределяющих задачи над user-space софтом... Это не под силу 99% разработчикам (я не понтуюсь - тоже вхожу пока в их число :)).
В идеале смысл многопоточности состоит в общении потоков между друг другом. Т.е. когда один поток говорит другому "о, коллега, у меня тут запрос пришёл и кое-что обновилось - обнови ка и у себя это". mayevski выше сказал - мол, если есть куча процессов - нафиг городить многопоточность.. а вот представьте себе 128 ядер. И у них есть общая настроечка такая - скажем счётчик посещений. Вы только представьте сколько можно сэкономить буквально на этой мелкой штуке если использовать распределённую память. Только при этом особый выигрыш будет при традиционной shmem и pthreads и, как следствие, Си. В других же случаях, тот же APC у пхп при обслуживании 128 потоков грозит быть затычкой для них всех (т.к. лочить будет).
В общем тема животрепещущая, на мой взгляд. Кто использовал Linux Virtual Server - скажите он серьёзно может делать 1 логическую вычислительную единицу даже из нескольких компов, не то чтобы ядер?
Про лямбда-функции, каюсь, я не имел ввиду здесь разгон в скорости (создание какой-нибудь простой фунции будет быстрее), но выглядит куда понятнее.
1,'b'=>2,'c'=>3);
$lfunc = create_function('&$v,$k', '$tmp=$k.$v;');
function z(&$v, $k) {
}
$t=microtime(1);for ($i=0;$i$v) $tmp=$k.$v;echo (microtime(1)-$t)."\n";
$t=microtime(1);for ($i=0;$i
результат:
mocksoul@home ~ $ php t.php
0.258806943893
0.515441179276
0.274258108139
О том как добится чтобы пхп запускал потоки - см. bin-environment в предоставленном мной конфиге. И 128 потоков PHP - я забыл упомянуть - это для 8-ядерного сервера хорошо... =) Другими словами прочитав статью головой-то все равно думать надо. Это не HowTo.
Очень важный момент - ?> - действительно лучше не использовать в конце файла. Толку от неё - ноль.
echo 'asd' . 'dsa' против echo 'asd', 'dsa' толком никакой разницы не несут. Равно как и echo 'asd' против echo "asd". Выбирать что использовать лучше из общепринятых стандартов - двойные кавычки ТОЛЬКО когда в этом есть смысл (т.е. нужен парсинг переменных внутри и тп). И echo 'asd' . 'dsa' вместо конкантенации параметров запятой. Причём по скорости разницы можно сказать что вообще нет. Задумываться об этом глупо потому что в любой PHP-программе есть 99.99% мест заслуживающих большего внимания ;).
echo или print.. print используется теми кто к нему привык - т.е. пересаживается с Си, например. В php-мире превалирует-таки echo. Это факт.
diablitozz, проблемы многопоточности как явления нету, конечно. Есть проблема что программы создавать с поддержкой многопоточности не в пример сложнее чем линейные. И даже дело не в самом написании, а в проблемах которые возникают потом абсолютно внезапно в каком-то одном конкретном случае. Проблема может и через год возникнуть.
Кстати говоря забавно. Попробовал потоки в питоне на 8-ядерном сервере. Удалось выжать максимум 250% из 800%. В то время как на си с pthreads четко 800% при 8 потоках :)). Ещё интересно что в питоне (да будь проклят этот gil) потоки переключаются сначала операционкой, потом ещё и самим питоном... а в си - при создании потока он буквально "вешается" на 1 ядро.т.е. 7 потоков там сжирают ровно 7 ядер из 8, одно пустует (естественно, они меняются), а в питоне получается что все ядра пыхтят но не на полную катушку.
Надо бы ещё с erlang поэкспериментировать...
А теперь представьте веб-приложение качественно нового уровня. Заходит юзер. Авторизуется. Какой-то поток берёт данные из бд. И таких юзеров в какой-то времени, допустим, тысяча. А теперь представьте что один юзер из авторизованных пишет сообщение другому. Традиционный вариант - каждый раз смотреть где-либо (в бд, скажем) есть новые сообщения или нет. А тут один поток просто говорит другому, мол "нью мессадж". И всё.
Конечно, всё не так просто. Конечно, это потом достаточно проблематично распределить на более чем 1 сервер. Но event-driven программирование явно шустрая штука.
Локи локами, но тут уже гораздо большее влияние на производительность оказыывает программист и архитектура приложения в целом.
Отсюда вывод что в теории создавать оооочень большое количество ядер - будет дешевле.
Предположим сервер. Например с 2 ядрами. Сейчас большинство PHP (например) программистов легко могут их занять. А теперь представьте сервер с 128 ядрами (а ведь будут массово). Чтобы эффективно их все использовать и не тратить до 30% времени на всякую чепуху (парсинг require в том же пхп) нужно использовать распределённую память и проч. Думаю огромный процент программистов высокоуровневых языков явно охренеет когда первый раз словит race condition. Начнёт читать про семафоры и подумает - что программист он не ахти какой оказывается.
А как заюзать многопоточность в высокоуровневых языках? PHP - вариант только с колво_ядер+1 поток при fastcgi + такое же кол-во потоков управляющего веб-сервера. Ну либо огромная куча форков апача с PHP как модулем (причём затраты на создание форка - кака). И каждый чертов PHP будет делать сотни две stat вызовов в фс, даже если стоит APC при каждом запросе.. (типичная ситуация для пользователей фреймворков а-ля ZendFramework). Уже абсурд. Питон. Есть потоки, после загрузки в основном только бизнес-логика работает. Но есть чёртов Global Interpreter Lock, который не позволяет-таки эффективно грузить много ядер (ну +20-30% будет максимум). Опять же питон придётся форкать. Появятся сложности с распределённой памятью (либо необходимый размер ОЗУ для работы вырастет в количестве форков, либо нужно добавлять ещё один хрупкий (при недостаточной сообразительности программиста) элемент такой как - отдельный распределённый кеш (который может создать массу race condition сложно уловимых). Как вариант - си с pthreads в который засовывать питон. Но это требует уже оочень высокой квалификации иначе есть угроза отстутствия прироста скорости вообще :).
Помимо всего прочего современный разработчик обязан делать софт не только многопоточным, но ещё и с возможонстью кластеризации. Два сервера с 4 ядрами явно лучше чем 1 с восемью.
Разрабатывать такие приложения очень сложно. Как правило требуется тратить огромное количество усилий на документирование и ТЗ иначе следующий или просто новый программист ничего не сможет понять.
Отчасти это причина почему у Java программистов обычно зарплата качественно выше чем PHP и находится на уровне Python/C.
Остаётся конечно возможность реализации совсем сложных решений - kernel-space многопоточников распределяющих задачи над user-space софтом... Это не под силу 99% разработчикам (я не понтуюсь - тоже вхожу пока в их число :)).
В идеале смысл многопоточности состоит в общении потоков между друг другом. Т.е. когда один поток говорит другому "о, коллега, у меня тут запрос пришёл и кое-что обновилось - обнови ка и у себя это". mayevski выше сказал - мол, если есть куча процессов - нафиг городить многопоточность.. а вот представьте себе 128 ядер. И у них есть общая настроечка такая - скажем счётчик посещений. Вы только представьте сколько можно сэкономить буквально на этой мелкой штуке если использовать распределённую память. Только при этом особый выигрыш будет при традиционной shmem и pthreads и, как следствие, Си. В других же случаях, тот же APC у пхп при обслуживании 128 потоков грозит быть затычкой для них всех (т.к. лочить будет).
В общем тема животрепещущая, на мой взгляд. Кто использовал Linux Virtual Server - скажите он серьёзно может делать 1 логическую вычислительную единицу даже из нескольких компов, не то чтобы ядер?