Так ли быстр ваш Framework или хватит тестировать производительность Нello World

    На примере быстрейших фреймворков «Phalcon» и «handmade».
    Обгоняем Phalcon без компиляции исходных кодов.




    Почему именно Phalcon? Это довольно свежее и многообещающее решение в плане производительности, хотя на его месте может быть любой фреймворк (это станет ясно из статьи).

    Для тестирования использован phalcon 1.2.0beta1 64Bit для OpenSuse
    Из дополнительных подключенных библиотек PHP 5.3 была только php5-APC, для чистоты эксперимента.

    Руководствуясь мануалом создаем приложение Phaclon
    index.php
    <?php
    try {
        //Register an autoloader
        $loader = new \Phalcon\Loader();
        $loader->registerDirs(array(
            './app/controllers/',
            './app/models/'
        ))->register();
    
        //Create a DI
        $di = new Phalcon\DI\FactoryDefault();
    
        //Setting up the view component
        $di->set('view', function(){
            $view = new \Phalcon\Mvc\View();
            $view->setViewsDir('./app/views/');
            return $view;
        });
    
        //Handle the request
        $application = new \Phalcon\Mvc\Application($di);
    
        echo $application->handle()->getContent();
    
    } catch(\Phalcon\Exception $e) {
         echo "PhalconException: ", $e->getMessage();
    }
    

    ./app/controllers/IndexController.php
    <?php
    class IndexController extends \Phalcon\Mvc\Controller
    {
        public function indexAction()
        {
            echo "<h1>Hello!</h1>";
        }
    }
    


    Запускаем, работает, memory_get_usage() говорит, что использовано 692kb памяти, отличный результат.
    Apache Benchmark выдает 8707 rps:


    Изумительно, потрясающая производительность.

    Заглядываем в xdebug profile, оптимизм проходит, и многое становится ясно. Что это приложение сделало такого особенного? Это просто echo. Ничего не имею против Phalcon, но как быть с более сложными задачами?

    Можно ли сделать PHP-фреймворк, который будет быстрее Phalcon, без необходимости компиляции исходных кодов? Не вопрос, сейчас сделаем. А потом еще и докажем тестами, что он быстрее.

    Создаем конкурента, назовем его Handmade
    index.php:
    <?php
    require_once './Autoloader.php';
    
    $autoloader = new Autoloader(array(
    	'paths'=>array(
    			'./app',
    			'./lib'
    	)		
    )); 
    
    $app = new Application();
    $app->run();
    

    Autoloader.php
    Автозагрузчик решил взять из своего проекта, сэкономил время.
    Исходный код тут, ничего особо навороченного, обычная PSR-0 совместимая автозагрузка.

    ./lib/Application.php
    <?php
    class Application
    {
    	public function run()
    	{
    		$uri = $_SERVER['REQUEST_URI'];
    		
    		$paths = explode('/' , $uri);
    		
    		if(isset($paths[0]) && !empty($paths[0])){
    			$controller = ucfirst(strtolower($paths[0])).'_Controller';
    		}else{
    			$controller = 'Index_Controller';
    		}
    		
    		if(isset($paths[1]) && !empty($paths[1])){
    			$action = strtolower($paths[1]).'Action';
    		}else{
    			$action = 'indexAction';
    		}
    		
    		$controller = new $controller;
    		$controller->$action();
        }
    } 
    

    app/Index/Controller.php
    <?php
    class IndexController extends Controller
    {
        public function indexAction()
        {
            echo "<h1>Hello!</h1>";
        }
    }
    


    Запускаем, работает, memory_get_usage() говорит, что использовано 624kb памяти. Отличный результат!

    Apache Benchmark выдает 11793 rps:


    Вуаля 11793 против 8707 rps, оказалось не так сложно, 15 минут программирования, без оптимизаций.
    Осталось построить красивые графики и поместить их ближе к заголовку статьи.

    Наверное, возникнет вопрос, с чего это вдруг я решил что, можно сравнивать его любимый framework «вставить название» со своей халтурной поделкой у которой и функционала то нет особо никакого. Загляните в интернет, полно тестов платформ несравнимых по целям и функционалу.

    В этом вся суть топика, давайте взглянем на полезную нагрузку двух сравниваемых решений. Откроем profile, который нам предоставляет xdebug. Для визуализации буду использовать kcachegrind.

    Что мы видим:
    Phalcon Handmade



    Оба решения выполняют практически одинаковую нулевую работу.

    К чему все это.

    Как разработчик я часто присматриваюсь к различным решениями, немаловажную роль для меня играет производительность используемой платформы. Но, к сожалению, открыв очередной framework я не могу понять его реальной производительности, разработчики предоставляют тест Hello World, который совершенно ни о чем не говорит. Сложно сориентироваться, остается выяснять реальную производительность той или иной платформы основываясь на личном опыте и понимании того, что очевидно тормозит систему.
    Такие индикаторы как:
    • большое количество «магии»
    • излишняя абстракция и избыточная функциональность
    • повсеместное использование DI Container
    • архитектура, основанная на событийной модели (не путать с Event-driven PHP)

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

    Мораль

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

    Similar posts

    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 11

      +3
      Статья, как вступление к анонсу своего фреймворка :)
        +7
        Вопрос производительности языка программирования или фреймворка это даже не пятый и не десятый по важности для подавляющего большинства случаев веб разработки.
        Сегмент клепания одинаковых сайтов-визиток, да интернет магазинов пластиковых окон/гидромассажных ванн, умещающихся на vps за 50 рублей/год учитывать не будем.
        Гораздо важнее тут будут скорость разработки и лёгкость дальнейшей поддержки и написания кода. Если вы не пишете числодробилку, то в конце-концов у вас всё почти наверняка упрётся не во фреймворк, а в базу данных(читай жёсткий диск) и пропускную способность канала.

        Пока вы на своём мегабыстром фреймворке будете полгода-год клепать очередной фейсбук, инстаграм или что-то там ещё, другая команда возьмётся делать аналогичный сервис на каком-нибудь в 10 раз более медленном rails, но выпустит проект в разы быстрее, с более качественным кодом и заберёт себе всех ваших потенциальных клиентов. Когда у них будут уже сколько-то десятков или даже сотня тысяч пользователей в сутки на одном сервере, и одного кеширования станет недостаточно, то они тупо докупят ещё сервера.
        Лишний сервер стоит копейки по сравнению с зарплатами разработчиков(грубо говоря месяц работы разработчика стоит как аренда 5-20 серверов на том же хетзнере или 2-3 хороших серверов на высококачественном хостинге).
        А ещё может быть(и что даже скорее всего и случится) такой посещаемости никогда и не будет, все усилия провалятся, сервис «не взлетит». Команда, делающая быстро на «тормозном фреймворке», начнёт и может быть даже успеет выпустить новую версию очередного проекта, а вы к тому времени только закончите свою первую версию того-что-вы-там-делали, и ещё позже вам лишь предстоит понять, что проект «не взлетел».

        Мораль на самом деле такая: фейсбуком вы всё равно никогда не станете, а если и станете, то в большинстве случаев становиться им будете очень постепенно. Решайте проблемы производительности по мере их наступления. Выигрывая в производительности кода, вы обязательно будет проигрывать в чём-то другом. Самый важный и дорогой ресурс в нашей жизни, это время. Оно стоит гораздо дороже железа.
          0
          По специфике работы мне приходится сталкиваться с проблемами производительности. Бывает так, что несколько десятков строк кода может помочь сэкономить на подключении пары серверов в систему (затраты день разработки, сервера же стоят годами и требуют оплаты). Хотя далеко не всегда все так просто.
          В целом с вами полностью согласен, об этом и пост.
            +1
            То ли дело 1 сайт на сервере держать, а другое дело 10! Профит очевиден же.
            Да и посыл статьи как я ее не понял не в том производительность — это самое главаное, а в том какие трудности есть в понимании реальной производительности фреймворков.
              0
              И вы верно уловили мысль.
            +2
            Вообще не понимаю синтетические тесты производительности фреймворков/языков программирования, когда в реальности в 99,9% все тормоза банально упираются банально в базу (и кривые руки которые пишут кривые запросы).
            На самом деле скорость выполнения скриптов вообще 20ое дело. И если она так важна, то следовательно проект высоконагруженный и суперпосещаемый, а следовательно проще добавить дополнительный сервер, и за счет грамотной монетизации (клиентура то есть, иначе откуда взяться нагрузкам), проект быстро отобьет затраченные на сервер деньги.
            На самом деле в случае гонки за скоростью обычно стоит выбирать — либо разрабатываем супергибкий движок, и он будет средним по скорости, либо же забиваем на гибкость, и пишем код так, чтобы все работло супер быстро. Вот кстати пример из реальной жизни — например используем мы супер крутяццкий ORM, извлекаем из БД 500 объектов, и в лучших традициях жанра ORM оборачивает каждый извлеченный элемент в объект. При большом количестве извлеченных объектов (200-300) задержка выполнения скрипта может варьироваться от 50 до 150 ms. И тут уже надо выбирать — либо гибкий ORM, либо выигрываем 50 ms в каких-то кейсах, но забивем на гибкость.
              0
              Как я полагаю гонка за «победы» в тестах среди разработчиков framework, заключается в предложении схожего функционала при большей производительности, только в таком случае есть смысл ее мерить, притом разница в результатах должна быть значительная. К сожалению эта гонка теперь сводится к кто быстрее выведет echo «Hello World».
              0
              Хех, какой вы хитрый ход сделали.
              Согласен тестировать Hello world нет смысла, так(!) как делаете это вы. Ваш так называемый «фреймворк» можно свести к нескольким строкам кода, вот так например twitto.org/
              Вы берете Full stack framework против обычного вызова метода (new $class)->$method(); и выдаете это за тест. Как раз Hello world если сравнивается на сайтах фреймворков то сравнивается типичная инициализация фреймворка включая самую отсылку контента клиенту. Т.е. var_dump(new Application) и var_dump(new Phalcon\DI\FactoryDefault) разницу видите? В вашем Application даже роутинга нет по сути. Т.е. Вы ждете от фреймворка как сами написали чтобы у него были Events и DI и роутинг, но сами это в свой Application не включили))) и сравниваете производительность))
              Тогда сравните уже мой handmade framework против вашего: ?php die('Hello world'); И кстати мне его легче расширить чем вам свой)))
                0
                Посмотрите результаты профайлинга. Я не просто так написал о полезной нагрузке.
                  0
                  О че вы конкретно говорите?
                  Профайлер не показывает DI\FactoryDefault, хотя там каждый раз создается больше 20 объектов. В общем Phalcon приложение каждый раз создает 25-30 объектов для full stack приложения, ваше же приложение создает 3 объекта, разницу чувствуете? Причем объекты не просто создаются а создаются с вычислениями это request, router, url, посылаются eventы при короче весь процесс. У вас же просто explode строки и вызов метода, больше ничего нет!!!
                  Поэтому если сравнить die('Hello world') и ваш App->run() это может претендовать на объективность, но никак не PhalconApp vs explode($_SERVER['REQUEST_URI']); $class->$method();
                    +1
                    Результат одинаков, там может быть создано сколько угодно много объектов они не создают полезную нагрузку в тесте Hello World. Если бы это был тест который смог показать во всей красе возможности фреймворка, скорость работы его структур и логики, вопроса не возникло бы. Любое маломальское приложение с бизнес логикой и данными показало бы более менее реальные результаты, нежели выбор кто скажет «Привет!»

              Only users with full accounts can post comments. Log in, please.