Последние темы


Новый тест производительности pdoTools + Fenom

  • Как-то раз я уже тестировал pdoTools и писал об этом в своем блоге. Тогда причиной послужило то, что в описании этого компонента был размещен скриншот одного комментария от какого-то пользователя, где он писал, что скорость по сравнению с getProducts у него получилась в 5(!!!) раз выше. Но на проверку это оказалось дезинформацией и после уговоров администрации modx.pro тот скриншот всё-таки убрали.

    К сожалению, статья утеряна вместе с другими статьями моего старого блога (авария на сервере), поэтому я решил снова проверить так ли быстр pdoTools, как заявляет автор. Тем более очень часто на форуме вижу как люди пишут про феноминальную скорость pdoTools + Fenom.
    Главной задачей данного теста была проверка скорости работы парсера.

    Я создал два тестовых сайта:
    http://test.wdevblog.net.ru/test1/index.php?id=1
    http://test.wdevblog.net.ru/test2/index.php?id=1


    Результаты (средние цифры):

    PHP 5.6

    getProducts + getPage (стандартный парсер MODX)

    Parse Time: 0.2122 s
    Total Time: 0.2204 s
    Source: database
    Memory: 6.5 mb
    

    pdoTools + Fenom

    Parse Time: 0.2167 s
    Total Time: 0.2273 s
    Source: database
    Memory: 13 mb
    

    PHP 7.0 (сейчас на сервере эта версия)

    getProducts + getPage (стандартный парсер MODX)

    Parse Time: 0.0526 s
    Total Time: 0.0572 s
    Source: database
    Memory: 2 mb
    

    pdoTools + Fenom

    Parse Time: 0.0359 s
    Total Time: 0.0474 s
    Source: database
    Memory: 2 mb
    

    Если пощелкаете переход по страницам, то результаты будут каждый раз немного отличаться, но в целом существенной разницы скорости работы парсера нет - PHP 5.6
    У pdoTools на PHP 5.6 больше расход оперативной памяти (в 2 раза).
    На число запросов к БД лучше не обращать внимания, т.к. эта цифра скорее всего не верная.

    Обновлено
    Добавил цифры для PHP 7.0. Картина для pdoTools + Fenom более красивая, но не очень существенно (~17%).


    Шаблоны и чанки.

    getProducts + getPage

    Шаблон страницы

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="description" content="">
        <meta name="author" content="">
        <link rel="icon" href="/favicon.ico">
    
        <title>MODX Test site</title>
    
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
        <style>
        body { padding-top: 5rem; }
        .starter-template { padding: 3rem 1.5rem; text-align: center; }
        </style>
        
      </head>
    
      <body>
    
        <main role="main" class="container">
    
    <h1>getProducts + getPage</h1>
        
    <div class="row">
    [[!getPage?
    &elementClass=`modSnippet`
    &element=`getProducts`
    &parents=`2`
    &includeTVs=`1`
    &includeTVList=`tv1,tv2,tv3,tv4`
    &limit=`20`
    &tpl=`sample_item`
    &pageNavTpl=`<li class="page-item"><a class="page-link" href="[[+href]]">[[+pageNo]]</a></li>`
    &pagePrevTpl=`<li class="page-item"><a class="page-link" href="[[+href]]">&laquo;</a></li>`
    &pageNextTpl=`<li class="page-item"><a class="page-link" href="[[+href]]">&raquo;</a></li>`
    &pageActiveTpl=`<li class="page-item active"><a class="page-link" href="[[+href]]">[[+pageNo]]</a></li>`
    &pageFirstTpl=` <li class="page-item"><a class="page-link" href="[[+href]]">Первая</a></li> `
    &pageLastTpl=` <li class="page-item"><a class="page-link" href="[[+href]]">Последняя</a></li> `
    ]]
    </div>
    
    <br class="clear" />
    <ul class="pagination">
    [[!+page.nav]]
    </ul>
    
    
    <div class="card card-body my-3 bg-secondary text-white" style="width: 300px; position: fixed; bottom: 15px; right: 15px; z-index: 1000;">
    <div>Query Time: [^qt^]</div>
    <div>Query Count: [^q^]</div>
    <div>Parse Time: [^p^]</div>
    <div>Total Time: [^t^]</div>
    <div>Source: [^s^]</div>
    <div>Memory: [[!ShowMemory]]</div>
    </div>
        
        </main>
        
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
    
      </body>
    </html>
    

    Чанк "sample_item"

    <div class="col-12">
        <div class="card card-body mb-3">
        
            <h5>[[+pagetitle:ucase]] - ID = [[+id]]</h5>
            
            <div>
            [[+tv.tv1:is=`1`:then=`
                 tv.tv1 ([[+tv.tv1]]) = 1
            `:else=`
                 tv.tv1 ([[+tv.tv1]]) != 1
            `]]
            </div>
            
            <div>
            [[+pagetitle:contains=`Док`:then=`
                Название ([[+pagetitle]]) содержит "Док"
            `:else=`
                Название ([[+pagetitle]]) не содержит "Док"
            `]] 
            </div>
            
            <div>
            [[+tv.tv2:lt=`5`:then=`
                 tv.tv2 ([[+tv.tv2]]) < 5
            `:else=`
                 tv.tv2 ([[+tv.tv2]]) >= 5
            `]]
            </div>
            
            <div>
            [[+tv.tv3:in=`3,4,5,6`:then=`
                 tv.tv3 ([[+tv.tv3]]) в массиве "3,4,5,6"
            `:else=`
                 tv.tv3 ([[+tv.tv3]]) не в массиве "3,4,5,6"
            `]]
            </div>
            
            <div>
            Вложенные условия (два уровня):<br>
            [[+tv.tv4:gt=`4`:then=`
                tv.tv4 ([[!+tv.tv4]]) > 4<br>
                [[+tv.tv4:lt=`30`:then=`tv.tv4 ([[+tv.tv4]]) < 30`:else=`tv.tv4 ([[+tv.tv4]]) >= 30`]]
            `:else=`
                 tv.tv4 ([[!+tv.tv4]]) <= 4<br>
                [[+tv.tv4:gt=`0`:then=`tv.tv4 ([[+tv.tv4]]) > 0`:else=`tv.tv4 ([[+tv.tv4]]) <= 0`]]
            `]]
            </div>
            
        </div>
    </div>
    

    pdoTools + Fenom

    Шаблон страницы

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="description" content="">
        <meta name="author" content="">
        <link rel="icon" href="/favicon.ico">
    
        <title>MODX Test site</title>
    
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
        <style>
        body { padding-top: 5rem; }
        .starter-template { padding: 3rem 1.5rem; text-align: center; }
        </style>
        
      </head>
    
      <body>
    
        <main role="main" class="container">
    
    <h1>pdoTools + Fenom</h1>
        
    <div class="row">
    {$_modx->runSnippet('!pdoPage', [
        'element' => 'pdoResources',
        'parents' => 2,
        'depth' => 0,
        'tpl' => 'sample_item',
        'limit' => 20,
        'sortby' => 'id',
        'includeTVs' => 'tv1,tv2,tv3,tv4',
        'tvPrefix' => 'tv_',
        'prepareTVs' => 0,
        'processTVs' => 0,
        'tplPage' => '@INLINE <li class="page-item"><a class="page-link" href="{$href}">{$pageNo}</a></li>'
        'tplPageActive' => '@INLINE <li class="page-item active"><a class="page-link" href="{$href}">{$pageNo}</a></li>'
        'tplPagePrev' => '@INLINE <li class="page-item"><a class="page-link" href="[[+href]]">&laquo;</a></li>'
        'tplPageNext' => '@INLINE <li class="page-item"><a class="page-link" href="[[+href]]">&raquo;</a></li>'
        'tplPageFirst' => '@INLINE <li class="page-item"><a class="page-link" href="{$href}">Первая</a></li>'
        'tplPageLast' => '@INLINE <li class="page-item"><a class="page-link" href="{$href}">Последняя</a></li>'
        'tplPagePrevEmpty' => ''
        'tplPageNextEmpty' => ''
        'tplPageFirstEmpty' => ''
        'tplPageLastEmpty' => '',
        'showLog' => 0
    ])}
    </div>
    
    <br class="clear" />
    <ul class="pagination">
    {$_modx->getPlaceholder('page.nav')}
    </ul>
    
    
    <div class="card card-body my-3 bg-secondary text-white" style="width: 300px; position: fixed; bottom: 15px; right: 15px; z-index: 1000;">
    <div>Query Time: [^qt^]</div>
    <div>Query Count: [^q^]</div>
    <div>Parse Time: [^p^]</div>
    <div>Total Time: [^t^]</div>
    <div>Source: [^s^]</div>
    <div>Memory: {$_modx->runSnippet('!ShowMemory')}</div>
    </div>
        
        </main>
        
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
    
      </body>
    </html>
    

    Чанк "sample_item"

    <div class="col-12">
        <div class="card card-body mb-3">
        
            <h5>{$pagetitle|upper} - ID = {$id}</h5>
            
            <div>
            {if $tv_tv1 == 1}
                 tv.tv1 ({$tv_tv1}) = 1
            {else}
                 tv.tv1 ({$tv_tv1}) != 1
            {/if}
            </div>
            
            <div>
            {if 'Док' in string $pagetitle}
                Название ({$pagetitle}) содержит "Док"
            {else}
                Название ({$pagetitle}) не содержит "Док"
            {/if}
            </div>
            
            <div>
            {if $tv_tv2 < 5}
                 tv.tv2 ({$tv_tv2}) < 5
            {else}
                 tv.tv2 ({$tv_tv2}) >= 5
            {/if}
            </div>
            
            <div>
            {if $tv_tv3 in list [3,4,5,6]}
                 tv.tv3 ({$tv_tv3}) в массиве "3,4,5,6"
            {else}
                 tv.tv3 ({$tv_tv3}) не в массиве "3,4,5,6"
            {/if}
            </div>
            
            <div>
            Вложенные условия (два уровня):<br>
            {if $tv_tv4 > 4}
                tv.tv4 ({$tv_tv4}) > 4<br>
                {if $tv_tv4 < 30}
                    tv.tv4 ({$tv_tv4}) < 30
                {else}
                    tv.tv4 ({$tv_tv4}) >= 30
                {/if}
            {else}
                 tv.tv4 ({$tv_tv4}) <= 4<br>
                 {if $tv_tv4 > 0}
                    tv.tv4 ({$tv_tv4}) > 0
                {else}
                    tv.tv4 ({$tv_tv4}) <= 0
                {/if}
            {/if}
            </div>
            
        </div>
    </div>
    
  • Добавил цифры для PHP 7.0. Картина для pdoTools + Fenom более красивая, но не очень существенно (~17%).

  • Более усложненный вариант. 3 вызова сниппета на странице по 20 элементов.

    PHP 7.0

    getProducts + getPage

    Parse Time: 0.1684 s
    Total Time: 0.1760 s
    Source: database
    Memory: 2 mb
    

    pdoTools + Fenom

    Parse Time: 0.0849 s
    Total Time: 0.1043 s
    Source: database
    Memory: 2 mb
    

    Хороший результат у pdoTools + Fenom.

  • хм, на сложных сайтах действительно прирост почти в 2 раза. Недурно. Но, признаюсь, работал с pdoTppls + Fenom, не понравилось:

    1. Тащить зоопарк, который, если объективно, делает из modx совсем другую систему... Ну такое.
    2. Крайне хреново работает парсер. Тег {ignore} не работает как таковой. Хочешь JS на странице - занимайся любовью с выставлением пробелов перед фигурной скобкой.
    3. Если смешивать феном и стандартный синтаксис, то скорость получается нестабильной. Об этом даже сам Василий писал. А на старых проектах это будет всяко + многие дополнения не перешли на феном. Т.е. эта смесь будет всегда.

    Короче, жутко на любителя тема.

  • @pooding в точку

 

Последние комментарии

  • M

    @Andchir , спасибо. Проблема и правда была в одном из плагинов, который на другом сайте нормально работает

    Читать далее
  • Что нового в Shopkeeper 4.0.3:

    Исправлено некорректное определение языка по умолчанию В настройках в админке скрываются пароли. Добавлена возможность загружать картинки для категорий. shopkeeper.js - добавлена функция updateProductsPrice() для поддержки текстовых полей для цены. Twig-функции contentList() и includeContent() вынесены в отдельный класс. Добавлено событие "order.before_create". Сортировка всех полей типа контента перетаскиванием. Автоматическое сохранение сортировки полей при сохранении типа контента (не нужно нажимать на отдельную кнопку). В интерфейсе админа добавлено поле поиска для списка Composer-пакетов.

    Скачать можно на главной странице https://modx-shopkeeper.ru/

    Читать далее
  • Вот этот плагин:
    0_1550334109280_screenshot_022.png

    Вроде по умолчанию он выключен. Надо включить. Но плагин работает только на редактирование товаров, при удалении он делалать ничего не будет. Только что проверил кнопку, всё работает корректно, фильтры удаляются и добавляются, когда нужно. Но нужно очищать корзину после удаления товаров (возможно баг).

    Читать далее
  • J

    @Andchir Если нажимаю кнопочку "Обновить значения", то в фильтрах появляются как раз те самые удаленные значения фильтра.. Потом приходится Ручками выбирать эти удаленные значения.
    вот так выглядит Управление фильтрами когда удаляешь ручками: https://yadi.sk/i/_zw64CGkZ_sAYg
    А вот так выглядит когда просто нажимаешь "Обновить значения": https://yadi.sk/i/7WFbXC6xV5sQAw (красным выделено, то что приходится постоянно удалять

    Читать далее