Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.

Реклама


**Как получить V.I.P** (Перейти)
Чтобы заказать рекламу на Pro-Pawn.Ru, обращайтесь в Skype.
Баннерная реклама 200руб/мес, Текстовая 100руб/мес.
Показано с 1 по 5 из 5
  1. #1
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Онлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,666
    Репутация:
    2145 ±

    Сравнение производительности кода на Pawn (профилирование)

    Привет всем участникам Pro-Pawn.
    В данном уроке я объясню вам, как сравнивать производительность разных вариантов кода. Сделано это будет с помощью написанного мной профайлера.

    Примеры вопросов, на которые можно найти ответ с помощью профилирования:
    • Работает ли функция strcat быстрее, чем format, и если да, то в каких случаях?
    • Как лучше проверять подключение игрока: с помощью IsPlayerConnected или добавлением в итератор (foreach.inc) и использованием функции Itter_Contains ?



    Код профайлера:
    PHP код:
    // Profiler v1.3 (copyright (c) 2014-2017 Daniel_Cortez)  \\ Pro-Pawn.ru
    // Условия использования данного кода: http://pro-pawn.ru/showthread.php?12585


    /*======== Настройки =========================================================*/
    // Кол-во итераций в циклах.
    const PROFILER_ITERATIONS_MAJOR 10_000;
    const 
    PROFILER_ITERATIONS_MINOR 1_000;

    // Названия отрывков кода.
    new const code_snippets_names[2][] =
    {
        {
    "отрывок 1"},
        {
    "отрывок 2"}
    };

    // Здесь вы можете объявить переменные, используемые в профилируемых отрывках кода
    // и выполнить некоторые действия непосредственно перед профилированием.
    #define Prerequisites();\
        // <ваш код>

    /*
        Собственно, сами отрывки кода, которые нужно тестировать.
        Если код состоит из нескольких строк, переносите их обратным слэшем.
        Пример:
        #define CodeSnippet1();\
            DoSomething();\
            DoSomethingElse();
    */
    #define CodeSnippet0();\
        // <ваш код>

    #define CodeSnippet1();\
        // <ваш код>
    /*======== Конец настроек ===================================================*/



    // Не рекомендую изменять следующий код, если вы в нём не разбираетесь.
    #tryinclude <a_samp>
    #if defined _samp_included
        #define LINE_BREAK ""
    #else
        #define LINE_BREAK "\n"
        #include <core>
        #include <time>
        #define GetTickCount() tickcount()
    #endif

    #define _PROFILE_START(%0)\
        
    __t[%0] = GetTickCount();\
        for (
    __j 0__j PROFILER_ITERATIONS_MINOR; ++__j)\
        {
    #define _PROFILE_END(%0)        __t[%0] = GetTickCount()-__t[%0]

    #if defined _samp_included
        #define PROFILE_START(%0);    _PROFILE_START(%0)
        #define PROFILE_END(%0);\
            
    }\
            
    _PROFILE_END(%0);
    #else
        #define PROFILE_START(%0);    _PROFILE_START(%0)
        #define PROFILE_END(%0);\
            
    }\
            if ((
    _PROFILE_END(%0)) < 0) {--__i; continue;}
    #endif

    #define CODE_SNIPPET_EXISTS(%0)\
        
    (sizeof(code_snippets_names) >= ((%0) + 1)) && (defined CodeSnippet%0)


    new 
    code_snippets_time[sizeof(code_snippets_names)] = {0, ...};

    main()
    {
        new 
    __i__j__t[sizeof(code_snippets_names)];
        
    #emit    zero.pri
        #emit    lctrl        7
        #emit    stor.s.pri    __i
    #if CODE_SNIPPET_EXISTS(2)
        
    static const ending[] =
        
    #if (sizeof(code_snippets_names) <= 4)
            
    "ка";
        
    #else
            
    "ков";
        
    #endif
        
    printf(
            
    "Тестирование: %d отрыв%s кода." LINE_BREAK,
            
    sizeof(code_snippets_names), ending
        
    );
    #else
        
    printf(
            
    "Тестирование: <%s> vs <%s>" LINE_BREAK,
            
    code_snippets_names[0], code_snippets_names[1]
        );
    #endif
        
    static const JIT_status_strings[2][] =
            {
    "интерпретируемый""с JIT-компиляцией"};
        
    printf(
            
    "Режим: %s, %dx%d итераций.\a" LINE_BREAK,
            
    JIT_status_strings[__i],
            
    PROFILER_ITERATIONS_MAJORPROFILER_ITERATIONS_MINOR
        
    );
        
    Prerequisites();
        for (
    __i 0__i PROFILER_ITERATIONS_MAJOR; ++__i)
        {
            
    PROFILE_START(0);
            
    CodeSnippet0();
            
    PROFILE_END(0);
            
    PROFILE_START(1);
            
    CodeSnippet1();
            
    PROFILE_END(1);
    #if CODE_SNIPPET_EXISTS(2)
            
    PROFILE_START(2);
            
    CodeSnippet2();
            
    PROFILE_END(2);
    #endif
    #if CODE_SNIPPET_EXISTS(3)
            
    PROFILE_START(3);
            
    CodeSnippet3();
            
    PROFILE_END(3);
    #endif
    #if CODE_SNIPPET_EXISTS(4)
            
    PROFILE_START(4);
            
    CodeSnippet4();
            
    PROFILE_END(4);
    #endif
    #if CODE_SNIPPET_EXISTS(5)
            
    PROFILE_START(5);
            
    CodeSnippet5();
            
    PROFILE_END(5);
    #endif
    #if CODE_SNIPPET_EXISTS(6)
            
    PROFILE_START(6);
            
    CodeSnippet6();
            
    PROFILE_END(6);
    #endif
    #if CODE_SNIPPET_EXISTS(7)
            
    PROFILE_START(7);
            
    CodeSnippet7();
            
    PROFILE_END(7);
    #endif
    #if CODE_SNIPPET_EXISTS(8)
            
    PROFILE_START(8);
            
    CodeSnippet8();
            
    PROFILE_END(8);
    #endif
    #if CODE_SNIPPET_EXISTS(9)
            
    PROFILE_START(9);
            
    CodeSnippet9();
            
    PROFILE_END(9);
    #endif
    #if CODE_SNIPPET_EXISTS(10)
            
    PROFILE_START(10);
            
    CodeSnippet10();
            
    PROFILE_END(10);
    #endif
    #if CODE_SNIPPET_EXISTS(11)
            
    PROFILE_START(11);
            
    CodeSnippet11();
            
    PROFILE_END(11);
    #endif
    #if CODE_SNIPPET_EXISTS(12)
            
    PROFILE_START(12);
            
    CodeSnippet12();
            
    PROFILE_END(12);
    #endif
    #if CODE_SNIPPET_EXISTS(13)
            
    PROFILE_START(13);
            
    CodeSnippet13();
            
    PROFILE_END(13);
    #endif
    #if CODE_SNIPPET_EXISTS(14)
            
    PROFILE_START(14);
            
    CodeSnippet14();
            
    PROFILE_END(14);
    #endif
    #if CODE_SNIPPET_EXISTS(15)
            
    PROFILE_START(15);
            
    CodeSnippet15();
            
    PROFILE_END(15);
    #endif
            
    for (__j 0__j sizeof(code_snippets_names); ++__j)
                
    code_snippets_time[__j] += __t[__j];
        }
        for (
    __i 0__i sizeof(code_snippets_names); ++__i)
            
    printf(
                
    "%s: %d" LINE_BREAK,
                
    code_snippets_names[__i], code_snippets_time[__i]
            );
        
    printf("\a\a" LINE_BREAK);


    Условия использования:

      Открыть/закрыть
    1. Вам предоставляется право на копирование данного ПО, изменение и распространение при соблюдении других условий данной лицензии.
    2. Данное ПО предоставляется "как есть", без каких-либо гарантий (как явно выраженных, так и подразумеваемых).
      Автор ПО не несёт никакой ответственности за ущерб, причинённый в результате использования данного ПО и/или каких-либо других действий с ним.
    3. Во всех производных формах данного ПО должно заявление об авторстве и ссылка на страницу с данной лицензией должны оставаться в неизменном виде (т.е. как в оригинале). Также должно присуствовать явное упоминание того, что это производная работа, а не оригинал.
    4. Вы можете копировать, распространять и публиковать настройки профайлера отдельно - в этом случае указание авторства и ссылки на данную страницу не требуется.


    А теперь более простым языком*:
    1. Не выдавайте данный код за свой.
    2. Строки с упоминанием об авторстве и ссылкой на эту страницу должны оставаться в коде, в неизменном виде.
    3. Вы можете изменять код, если соблюдаются остальные условия использования (например, можете удалить все комментарии, кроме копирайта и ссылки на эту страницу).
    4. Если вы публикуете изменённую версию профайлера, обязательно указывайте, что это изменённая версия, а не оригинал.
    5. Настройки профайлера не попадают под эти условия, можете делать с ними всё, что захотите.

    *Приведённое выше упрощённое содержание не является полной лицензией.


    Настройка и использование:

    Для начала разберём назначение каждой настраиваемой константы:
    • Количество итераций цикла профилирования.
      PROFILER_ITERATIONS_MINOR - кол-во итераций перед измерением времени выполнения.
      PROFILER_ITERATIONS_MAJOR - кол-во измерений времени.
      Весь процесс профилирования сделан с помощью вложенных циклов. Таким образом уменьшаются погрешности от многократных вызовов GetTickCount.
      Также сглаживаются погрешности из-за разной нагрузки на ЦП в разные моменты времени. Например, во время профилирования может включиться запланированная по расписанию проверка антивирусом - это намного меньше повлияет на результаты профилирования в случае с вложенными циклами.
    • Названия отрывков кода.
      Для этой цели предназначен массив строк code_snippets_names.
    • Отрывки кода.
      Для указания сравниваемых отрывков кода предназначены макросы "CodeSnippet0();", "CodeSnippet1();", ... "CodeSnippet15();".
      Также для подготовительных действий (объявление и инициализация переменных, etc.) есть макрос Prerequisites.

    Рассмотрим использование профайлера на примере измерения производительности функций format и strcat для конкатенации строк:
    PHP код:
    /*======== Настройки =========================================================*/
    const PROFILER_ITERATIONS_MAJOR 10_000;
    const 
    PROFILER_ITERATIONS_MINOR 1_000;

    new const 
    code_snippets_names[2][] =
    {
        {
    "format"},
        {
    "strcat"}
    };

    #define Prerequisites();\
        
    static const str1[] = "1234567890123456789012345678901234567890";\
        static const 
    str2[] = "1234567890123456789012345678901234567890";\
        new 
    buffer[128];

    #define CodeSnippet0();\
        
    format(buffersizeof(buffer), "%s%s"str1str2);

    #define CodeSnippet1();\
        
    buffer str1strcat(bufferstr2);
    /*======== Конец настроек ====================================================*/ 


    Автор статьи: Daniel_Cortez
    Специально для Pro-Pawn.ru
    Копирование данной статьи на других ресурсах без разрешения автора запрещено!
    Последний раз редактировалось Daniel_Cortez; 03.05.2017 в 18:32. Причина: v1.3
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

  2. 12 пользователя(ей) сказали cпасибо:
    $continue$ (16.08.2015)Alanchick (17.01.2016)Camelot (18.08.2015)franked (19.02.2016)Hidden (17.08.2015)Osetin (16.08.2015)Redsan (09.10.2016)Sp1ke (18.08.2015)untonyst (16.08.2015)wAx (16.08.2015)[ForD] (09.10.2015)^_^ (16.08.2015)
  3. #2
    Аватар для untonyst
    Младший сержант

    Статус
    Оффлайн
    Регистрация
    15.03.2015
    Адрес
    Slobodskoy
    Сообщений
    663
    Репутация:
    234 ±
    Все равно скопипастят
    Младший сержант Стяжкин | ЧСВ группа в ВКонтакте NEW

  4. Пользователь сказал cпасибо:
    $continue$ (16.08.2015)
  5. #3
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Онлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,666
    Репутация:
    2145 ±
    Обновил код профайлера, теперь он должен работать не только на сервере SA:MP, но и под управлением оригинального интерпретатора Pawn.
    В алгоритм измерения скорости пришлось добавить обход проблемы, при которой функция tickcount почему-то возвращает неправильные значения.
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

  6. #4
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Онлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,666
    Репутация:
    2145 ±
    Ещё одно обновление. Теперь можно профилировать от 2 до 16 отрывков кода, не внося изменений в код самого профайлера.
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

  7. #5
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Онлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,666
    Репутация:
    2145 ±
    Добавил к переменным в коде профилирования префикс "__". Теперь в макросах Prerequisites и CodeSnippet* можно объявлять и использовать переменные с именами "i", "j" и "t" без конфликта имён.
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •