транзакции дело нужное, когда идет обсчет каких-нить финнсов... с одного списали. при попытке накинуть другому получили ошибку. потеряли бабло у клиентов, работу и самоуважение. =)
Кто-нибудь использует какую-либо имплементацию Berkeley DB помимо SQL и в каких случаях? Авторизация/логин ? Еще что-нибудь ?
Доброго времени суток всем. Меня всегда мучал такой вопрос - о целесообразности использования классов. У меня сложилось такое впечатление, что их использование существенно увеличивает время генерации страницы по сравнению с обычным "карявым" методом. Так оно или кажется? Особено это проявляется в cms'ках, когда при генерации страницы скажем с документами, в том числе и подругажаются все классы из конфигурации. Пусть они большинство ихне выполняется, но в целом же в кода они присутствуют, значит ли это что под них выделяются системные ресурсы?
botton Все зависит от архитектуры приложения. Обычно подгружается только то, что нужно. В архитектуре MVC в простом сайте подгружается порядка 5-8 классов. Сама специфика этой архитектуры, вроде бы, подразумевает тот факт, что данные в циклах будут перебираться по несколько раз. Безусловно, это увеличивает время выполнения приложения. Но лучше потратить 500$, чтобы увеличить мощность сервера для MVC, чем нанимать на 3 месяца программиста за 2000$/месяц, чтобы тот выполнил ТЗ, которое на MVC мог бы выполнить зи 1 месяц. Узким местом является БД. Практически все CMS грешат этим -- они делают по 50 запросов на простейшую страницу, отсюда и время выполнения порядка 1 секунды. И это независимо от того, написаны ли они на классах или нет. Взять, к примеру, phpNuke Просто когда разрабатываешь, нужно думать головой, оценивать код на рациональность и возможность доработки.
Недавно проверил скорость функций: array_intersect и array_diff, и удивился, как медленно они работают в отличии от других языков. Например в "Матиматике" аналогичные функции работают в 100 раз быстрее. Я засекал время за которое php выполняет такой вот код: PHP: for($i=0;$i<100;$i++) $b1=array_intersect($b[0],$b[$i]); , где $b[$i] - массив длинны 1000, наполненный случайными целыми числами из диапазона от 0 до 1000. В среднем у меня этот тест выполняется 10 секунд. Придумал аналог для array_intersect: PHP: function intersect($a1, $a2) { $a2=array_flip($a2); $a3=array(); foreach($a1 as $k)if($a2[$k]!==null)$a3[]=$k; return $a3; } , который дает 40% экономии времени. Это конечно не впечатляет, но говорит о кривости array_intersect. Думаю, что если возникнет задача многократного использования array_intersect или array_diff, то лучше будет загнать исходные данные в БД и обработать их запросами, так как драйвера баз данных давно уже оптимизированны переоптимизированны, хотя возможно есть более рациональное решение этой задачи.
А такая функция PHP: function intersect(&$a1, &$a2) { if($a1===$a2)return($a1); $a3=array(); $b2=current($a2); if($b2!==false)foreach($a1 as $b1) { while($b1>$b2) { $b2=next($a2); if($b2===false)break(2); } if($b2==$b1)$a3[]=$b1; } return $a3; } работает в 10 раз быстрее стандартной array_intersect, при условии, что исходные массивы уже отсортированы по возрастанию. Большего ускорения средствами PHP врядли можно достичь, но до теоритического предела еше далеко.
Недавно обнаружил такое дело. Время выполнения некоторых операций PHP, при применении их к массивам, пропорционально зависит от количества элементов данного массива, при чем в некоторых случаях такая зависимость не имеет логичного основания и может быть устранена путем обертывания массива в объект, что позволяет иногда сэкономить кучу машинного времени. Подобное поведение я обнаружил для двух (или трех, как посмотреть) операций: ==, === и global. Пусть мы имеем: Код (Text): $a=range(0,1e5); //большой массив class wrap{ //Класс обертка public $a; public function __construct($a){ $this->a=$a; } } $w=new wrap($a); //Обернутый массив Теперь, при выполнении кода: Код (Text): $b=$a;$b===$a; //Иногда такое имеет практический смысл PHP сравнит каждый элемент массива с самим собой, а в таком случае: Код (Text): $x=$w;$x===$w; PHP сразу поймет, что сравниваемые переменные идентичны. Теперь, при выполнении кода: Код (Text): function f(){ global $a; count($a); } PHP потратит примерно столько же времени, как для Код (Text): function f(){ $a=range(0,1e5); count($a); } То есть, произойдет бессмысленный перебор всех элементов массива. Если воспользоваться оберткой: Код (Text): function f(){ global $w; $a=$w->a; count($a); } То по времени это будет аналогично такому Код (Text): function f(){ $a=$GLOBALS['a']; count($a); } Как я уже говорил, все дело в зависимости времени исполнения от размера массива. И по всей видимости это является артефактом старых версий PHP.
переменная $b становится копией массива $a. здесь же $x и $w ссылаются на 1 и тот же объект, очевидно что сравнить ссылке быстрее, если там был бы clone $w тест был бы более логичен, ну или $b = &$a. Но вообщем-то в highload наврятли это было бы узким местом.
ага. мы увеличили произв. примерно в 1000 раз перейдя с foreach на while. плюс кеширование данных в наследуемых объектах. у нас очень большие массивы объектов. =)
С highload я не работал никогда, пока что, это было лишь предположение. foreach вреале медленнее, тут где-то даже тесты были. В нашем проекте, когда начинали писать, начали юзать везде while, но так как не highload и не будет никогда, продолжил писать foreach, а то я всегда ресетить массив забываю. Но что бы в 1000 раз, блин, это на самом деле очень большие массивы =) ну нет, хранить ссылку и скопировать целиком объект(массив), не одно и тоже. надо бы затестить =\
А как дальше данные обрабатываются? Разве while (list($bla) = $bla2) или while ($bla = each($bla2)) быстрее foreach ($bla2 as $bla) ?
Kreker К сожалению, в PHP foreach работает совсем не так, как for или while. foreach сначала снимает полную копию исходного массива (медленно), и только потом начинает по ней циклить. Не понимаю, зачем разработчики сделали такую засаду. Наверняка можно было реализовать быстрее.
Функция list тут главный тормоз. Вообще можно делать так PHP: <? foreach ($arr as $k=>&$v) { и при изменении $v будет меняться элемент в массиве $arr. Этого нельзя сделат в цикле с each. Еще foreach не смещает внутренний указатель массива. Короче, сплошные плюсы.
admyx По ссылке в foreach можно передать только третий аргумент - foreach($a as $b=>&$c), но не первый и не второй. Я говорил о первом аргументе, об исходном массиве - из-за его копирования-то и происходят тормоза и трата памяти. Может, в будущих версиях этот косяк исправят. Или сделают настройку - возможность итерирования по массиву напрямую, без создания копий, для тех, кому они нафиг не нужны (мне, например. ) А те, кто боится поломать свой старый код, эту настройку у себя не трогают.
Dagdamor Дык о чем я и спрашиваю. Херово, что нельзя. А я что-то не понимаю - зачем передавать по ссылке третий аргумент? о_0 По феншую?
[vs] Я у себя потестю этот код Может, 440Гц как-то иначе делал, без each, например, пользовался не-ассоциативными массивами...
admyx Чтобы внутри цикла, если надо изменить значение массива, писать $c=12345; а не $a[$b]=12345; К слову, если пользуетесь вторым вариантом (с &), то сразу после цикла желательно писать unset($c); иначе эта переменная так и пойдет далее по коду как референс. И обычным способом проинициализировать ее не выйдет: PHP: <?php foreach($a as $b=>&$c) { ... // какой-то код } ... $c=0; // кажется, что инициализация переменной, на самом деле в последний элемент $a запишется 0 >:O UPD: Тег "php" за три года так и не поправили