Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 4 из 7 ПерваяПервая ... 2 3 4 5 6 ... ПоследняяПоследняя
Показано с 31 по 40 из 68
  1. #31
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от NewGreen Посмотреть сообщение
    И не только от процессора еще от ОСи на ПК/сервере.
    На сервере, обычно это GNU/Linux, на линуксе время теста может еще больше склониться в пользу нативной функции strcat.
    Как раз таки наоборот, на Linux интерпретатор байткода AMX организован эффективнее, чем в версии для Widnows, за счёт расширений GNU C (см. здесь, стр. 6, 71, 76).
    Впрочем, это вряд ли касается ситуации, когда код выполняется под JIT.

    IMHO, самый верный способ профайлинга - на сервере под Linux, желательно с JIT, там условия наиболее приближены к реальным (если не брать в расчёт аппаратную часть). Наверное, так и буду тестить в следующий раз. Главное не запускать тесты на хостинге - там обычно есть защита, которая автоматом вырубает сервер при большой нагрузке.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  2. 2 пользователя(ей) сказали cпасибо:
    $continue$ (04.07.2015) NewGreen (04.07.2015)
  3. #32
    Аватар для $continue$
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.08.2014
    Адрес
    г. Киров (aka Вятка)
    Сообщений
    1,487
    Репутация:
    276 ±
    Обновил #30 пост

  4. #33
    Аватар для NewGreen
    Пользователь

    Статус
    Оффлайн
    Регистрация
    29.09.2014
    Сообщений
    61
    Репутация:
    44 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Как раз таки наоборот, на Linux интерпретатор байткода AMX организован эффективнее, чем в версии для Widnows, за счёт расширений GNU C (см. здесь, стр. 6, 71, 76).
    Впрочем, это вряд ли касается ситуации, когда код выполняется под JIT.

    IMHO, самый верный способ профайлинга - на сервере под Linux, желательно с JIT, там условия наиболее приближены к реальным (если не брать в расчёт аппаратную часть). Наверное, так и буду тестить в следующий раз. Главное не запускать тесты на хостинге - там обычно есть защита, которая автоматом вырубает сервер при большой нагрузке.
    Согласен с Вами, в условиях приближенных к реальным, результат будет более объективным)

  5. #34
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    "Переключаемые" многострочные комментарии.
    Думаю, все знакомы с многострочными комментариями в Pawn:
    Код:
    /*
    SendClientMessage(playerid, -1, "Some text");
    */
    Но что, если вам вдруг нужно раскомментировать этот участок кода?
    Правильно, кроме стирания первых "/*" придётся выискивать и завершающие комментарий символы "*/".
    Это может оказаться проблемой, если приходится часто комментировать/раскомментировать длинный участок кода (например, при тестировании).
    На этот случай можно сделать комментарий "переключаемым":
    Код:
    /*
    SendClientMessage(playerid, -1, "Some text");
    // */
    Теперь добавим перед "/*" один слэш ("/"):
    Код:
    //*
    SendClientMessage(playerid, -1, "Some text");
    // */
    В итоге мы "нейтрализовали" многострочный комментарий.
    Чтобы включить его обратно, достаточно лишь убрать первый слэш.
    Обратите внимание: между последними двумя слэшами и закрытием многострочного комментария ("//" и "*/") стоит пробел.
    Они разделены пробелом, чтобы компилятор обрабатывал их именно как "//" и "*/", а не "/", "/*" и "/" - в этом случае компилятор подумает, что это вложенный комментарий, и выдаст варнинг.


    Пропуск инициализации ячеек массива нулями.
    При объявлении локальных массивов внутри функций компилятор не только резервирует место в стеке под массив, но и инициализирует все его ячейки нулями, чтобы в них не было мусорных значений.
    Сделано это из-за быдлокодеров, которые, пользуются переменными, забывая их инициализировать.
    Тем не менее, инициализация занимает некоторое время, да и польза от этого сомнительная, если вы способны отдавать отчёт своим действиям.
    К счастью, есть способ избежать потерь во времени, пропустив инициализацию:
    PHP код:
        SomeFunction()
        {
            
    // перед объявлением массива перейдём на метку skip_array_init
            
    goto skip_array_init;
            
    // объявляем массив
            
    new arr[256];
        
    skip_array_init:
            
    // в этом месте массив arr будет существовать, но он не будет инициализирован:
            // код инициализации существует, но он находится _до_ метки skip_array_init,
            // т.е. мы обошли этот код

            // дальше - код с использованием массива
        

    Скомпилируем код, а затем дизассемблируем его.
    Получим следующую последовательность инструкций:
    Код HTML:
    	; Начало функции SomeFunction.
    	proc
    	; И сразу же - переход на метку l.0 (см. далее).
    	jump		0
    	; Выделение места в стеке под массив из 16 ячеек (ffffffc0 означает "-16")
    	; (этот код никогда не сработает, переход на l.0 был безусловным).
    	stack		ffffffc0
    	; Заполнение массива нулями происходит побайтово,
    	; 16 ячеек - 64 байта (40 в шестнадцатеричной системе счисления).
    	zero.pri
    	addr.alt	ffffffc0
    	fill		40
    ; Метка, с помощью которой пропускается инициализация массива.
    l.0
    	; Установка вершины стека в то положение, когда выделено 16 ячеек под массив,
    	; Обратите внимание: в отличие от обычного создания массива,
    	; здесь массив не заполняется никакими значениями,
    	; происходит только резервирование пространства,
    	lctrl		5
    	add.c		ffffffc0
    	sctrl		4
    	; Код с использованием массива.
    	; ...
    	; Высвобождение пространства в стеке и возврат из функции.
    	stack		40
    	zero.pri
    	retn
    Если кому интересно, вот тест скорости:
      Открыть/закрыть
    PHP код:
    #include <a_samp>

    const PROFILE_ITERATIONS_MAJOR 1000;
    const 
    PROFILE_ITERATIONS_MINOR 1000;

    const 
    STRING_SIZE 512;


    const 
    SZ STRING_SIZE;

    #define _m1();\
        
    {new a[SZ];}
    #define method1();\
        
    _m1();_m1();_m1();_m1();_m1();_m1();_m1();_m1();_m1();_m1();

    #define _m2();\
        
    {goto skip_init;new a[SZ];skip_init:}
    #define method2();\
        
    _m2();_m2();_m2();_m2();_m2();_m2();_m2();_m2();_m2();_m2();


    bool:IsJITEnabled()
    {
        
    #emit    lctrl    7
        #emit    retn
        
    return true;
    }

    main()
    {
        
    printf(
            
    "Testing array initialization..." "\n"\
            
    "(%dx%d iterations, array size: %d, JIT status: %sabled)",
            
    PROFILE_ITERATIONS_MAJORPROFILE_ITERATIONS_MINOR,
            
    STRING_SIZEIsJITEnabled() ? ("en") : ("dis")
        );
        new 
    t1t2tij;
        
    t1 0t2 0;
        for(
    0PROFILE_ITERATIONS_MAJOR; ++i)
        {
            
    GetTickCount();
            for(
    0PROFILE_ITERATIONS_MINOR; ++j)
            {
                
    method1();
                
    method1();
                
    method1();
                
    method1();
                
    method1();
                
    method1();
                
    method1();
                
    method1();
                
    method1();
                
    method1();
            }
            
    t1 += GetTickCount()-t;
            
    GetTickCount();
            for(
    0PROFILE_ITERATIONS_MINOR; ++j)
            {
                
    method2();
                
    method2();
                
    method2();
                
    method2();
                
    method2();
                
    method2();
                
    method2();
                
    method2();
                
    method2();
                
    method2();
            }
            
    t2 += GetTickCount()-t;
        }
        
    printf(
            
    "method 1: %d" "\n"\
            
    "method 2: %d",
            
    t1t2
        
    );


    Макросы method1 и method2 сделаны, чтобы повторить в них создание локальных массивов по 10 раз.
    Кроме того сами макросы используются в функции main по 10 раз (итого получается 10x10 = 100 повторов).
    Это не что иное, как развёртывание циклов. Я сделал именно так, чтобы уменьшить погрешность от циклов и вызовов GetTickCount, таким образом, увеличив точность измерений.
    Также в процессе компиляции выдаётся куча варнингов, но они, опять же, из-за макросов, не обращайте на них внимания.
    Тест я запускал на массивах из 32, 256 и 512 ячеек, с включенным и выключенным JIT.
    Результаты следующие:
      Открыть/закрыть

    Код:
    Testing array initialization...
    (1000x1000 iterations, array size: 32, JIT status: disabled)
    method 1: 5581
    method 2: 47
    
    Testing array initialization...
    (1000x1000 iterations, array size: 32, JIT status: enabled)
    method 1: 2640
    method 2: 4
    Код:
    Testing array initialization...
    (1000x1000 iterations, array size: 256, JIT status: disabled)
    method 1: 31324
    method 2: 42
    
    Testing array initialization...
    (1000x1000 iterations, array size: 256, JIT status: enabled)
    method 1: 15106
    method 2: 3
    Код:
    Testing array initialization...
    (1000x1000 iterations, array size: 512, JIT status: disabled)
    method 1: 63840
    method 2: 40
    
    Testing array initialization...
    (1000x1000 iterations, array size: 512, JIT status: enabled)
    method 1: 29161
    method 2: 4

    Из измерений можно сделать вывод, что размер массива никак не влияет на результаты метода с пропуском инициализации массива.
    Но всё же от трюка не сильно много пользы. Да, цифры в тесте, казалось бы, большие, но не стоит забывать, что они получены с помощью 100 миллионов итераций. В нормальных же условиях время инициализации массива в 512 ячеек составит всего ~0.0006384 мс или ~0.0000006 секунды.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  6. 6 пользователя(ей) сказали cпасибо:
    #ball (15.08.2015) $continue$ (27.07.2015) L0ndl3m (27.07.2015) vovandolg (28.07.2016) [ForD] (27.07.2015) ^_^ (11.08.2015)
  7. #35
    Аватар для ^_^
    Übermensch

    Статус
    Оффлайн
    Регистрация
    25.11.2013
    Сообщений
    157
    Репутация:
    245 ±
    Тема обновлена, спасибо Daniel_Cortez и Londlem.

  8. #36
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от ^_^ Посмотреть сообщение
    Почему пропуск инициализации сокращает время декларации переменных?
    Во-первых, слово "декларация" в русском языке больше относится к юридической сфере.
    В программировании гораздо чаще упортебляется слово "объявление".
    Во-вторых, объявление переменных относится к высокоуровневым языкам.
    В скомпилированном коде никаких объявлений нет, есть только выделение стекового пространства.
    Нет, серьёзно, как ты вообще представляешь "сокращение времени декларации переменных"? Это какое-то ускорение набора букв на клавиатуре?
    Если имеешь в виду повышение производительности кода, то так и пиши.

    Цитата Сообщение от ^_^ Посмотреть сообщение
    пропускаем дефолтную инициализацию
    Нет такого слова в русском языке. Да и вообще, это русскоязычный форум, а не МКС или Брайтон-Бич.
    В русском языке для таких целей есть слово "обычный".

    Цитата Сообщение от ^_^ Посмотреть сообщение
    массив мануально инициализирован
    По мануалам что ли?
    Ок, шутки в сторону, есть в живом великорусском языке слово "вручную".

    Цитата Сообщение от ^_^ Посмотреть сообщение
    иницальные значения
    То же самое. "Начальные".

    Цитата Сообщение от ^_^ Посмотреть сообщение
    Декларируем массив
    См. самое начало поста.


    Цитата Сообщение от ^_^ Посмотреть сообщение
    PHP код:
    #define explicit^%0[%1]; goto _%1_%0;new %0[%1];_%1_%0: 
      Открыть/закрыть

    Да эта тема уже переполнена "правильным смыслом"...
    И да, зачем добавлять к названию метки размер массива? Название и без размера будет уникальным, нельзя же объявить 2 разных массива с одинаковыми именами и разными размерами.

    Могу предложить такой вариант:
    PHP код:
    #define noinit:%0[%1]; goto _noinit_%0;new %0[%1];_noinit_%0: 
    Использовать символ ^ я бы не стал, т.к. за ним нужно тянуться в верхний ряд клавиатуры, двоеточие в этом случае будет намного удобнее.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  9. #37
    Аватар для Desulaid
    лесоруб продакшен

    Статус
    Оффлайн
    Регистрация
    15.03.2015
    Адрес
    Slobodskoy
    Сообщений
    667
    Репутация:
    236 ±
    Еще есть многократное присваивание.

    Первый вариант:

    PHP код:
    new xyz;
    abc;
    abc;
    abc
    Второй вариант с многократным присваиванием

    PHP код:
    new xyz;


    abc
    Второй вариант быстрее и оптимизированнее.

    assembly version

    Первый вариант:
    PHP код:
    load.pri c ;Get abc
    stor
    .pri 8 ;Store it in X
    break    ; 20
    load
    .pri c ;Get abc
    stor
    .pri 4 ;Store it in Y
    break    ; 34
    load
    .pri c ;Get abc
    stor
    .pri 0 ;Store it in Z 
    Второй вариант:
    PHP код:
    load.pri c ;Get abc
    stor
    .pri 0 ;Store in X
    stor
    .pri 4 ;Store in Y
    stor
    .pri 8 ;Store in Z 

  10. #38
    Аватар для $continue$
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.08.2014
    Адрес
    г. Киров (aka Вятка)
    Сообщений
    1,487
    Репутация:
    276 ±
    Наверное стоит дополнить к посту #36, как инициализируется массив в Pawn:
    PHP код:
    static array[2000]; // взял специально так много 
    Это будет равно тому же:
    PHP код:
    #include <a_samp>

    main()
    {
        new array[
    2000];
        for(new 
    0sizeof(array); i++)
        {
            array[
    i] = 0;
        }

    Если откомпилировать на ASM, то будет видно:
    PHP код:
    CODE 0    0
    ;program exit point
        halt 0

        proc    
    main
        
    line 4
        
    line 5
        
    break    ; c
        zero
    .pri
        retn


    DATA 0    
    0
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

    STKSIZE 1000 
    Где dump - забивание 2000 ячеек в нули.

  11. #39
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от $continue$ Посмотреть сообщение
    Наверное стоит дополнить к посту #36, как инициализируется массив в Pawn:
    PHP код:
    static array[2000]; // взял специально так много 
    Это будет равно тому же:
    PHP код:
    #include <a_samp>

    main()
    {
        new array[
    2000];
        for(new 
    0sizeof(array); i++)
        {
            array[
    i] = 0;
        }

    В случае с new место под массив резервируется в стеке и сам массив будет существовать до тех пор, пока функция не завершит свою работу или пока не закончится локальный блок, внутри которого объявлен массив - что раньше. Если же объявить массив с помощью static, он всё время будет существовать в секции данных. И быть такого не может, чтобы те 2 куска кода компилировались одинаково.

    EDIT: Решил проверить, сравнил 2 идентичных отрывка кода.
    Отличие лишь в том, что в 1-м случае массив объявляется с помощью ключевого слова static, а во 2-м - с помощью new.
    Размер массивов задал 256, чтобы не так сильно засорять листинг.
    PHP код:
    main()
    {
        new 
    arr[256];
        for (new 
    0sizeof(arr); ++i)
            
    arr[i] = 0;

    PHP код:
    main()
    {
        static 
    arr[256];
        for (new 
    0sizeof(arr); ++i)
            
    arr[i] = 0;

    Компилируем с ключом "-a".
    Первый отрывок:
    Код:
    CODE 0	; 0
    ;program exit point
    	halt 0
    
    	proc	; main
    	; line 2
    	; line 3
    	; line 4
    	;$lcl i fffffffc
    	push.c 0
    	;$exp
    	jump 2
    l.0		; 1c
    	; line 4
    	inc.s fffffffc
    	;$exp
    l.2
    	load.s.pri fffffffc
    	const.alt 100
    	jsgeq 1
    	;$exp
    	; line 5
    	zero.alt
    	load.s.pri fffffffc
    	idxaddr
    	move.alt
    	zero.pri
    	stor.i
    	;$exp
    	jump 0
    l.1		; 60
    	stack 4
    	zero.pri
    	retn
    
    
    DATA 0	; 0
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    dump 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    
    STKSIZE 1000
    Второй отрывок:
    Код:
    CODE 0	; 0
    ;program exit point
    	halt 0
    
    	proc	; main
    	; line 2
    	; line 3
    	;$lcl arr fffffc00
    	stack fffffc00
    	zero.pri
    	addr.alt fffffc00
    	fill 400
    	; line 4
    	;$lcl i fffffbfc
    	push.c 0
    	;$exp
    	jump 2
    l.0		; 38
    	; line 4
    	inc.s fffffbfc
    	;$exp
    l.2
    	load.s.pri fffffbfc
    	const.alt 100
    	jsgeq 1
    	;$exp
    	; line 5
    	addr.alt fffffc00
    	load.s.pri fffffbfc
    	idxaddr
    	move.alt
    	zero.pri
    	stor.i
    	;$exp
    	jump 0
    l.1		; 80
    	stack 4
    	stack 400
    	zero.pri
    	retn
    
    
    STKSIZE 1000
    Как видно, в первом случае массив находится в секции данных. В функции main() место в стеке выделяется лишь под переменную i.
    Во втором же случае секция данных совершенно пустая и место под массив выделяется именно в стеке.

    Ч.т.д.
    Последний раз редактировалось Daniel_Cortez; 26.09.2015 в 20:43. Причина: пруфы
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  12. #40
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Объединение строк и массивов.

    Компилятор Pawn не умеет самостоятельно объединять неизменяемые (const) массивы, т.е. если объявить два постоянных массива с одинаковым содержимым, компилятор не станет разделять между ними одну копию содержимого.
    Пример:
    PHP код:
    #include <a_samp>

    main()
    {
        print(
    "Hello world!");
        print(
    "Hello world!");

    Здесь "Hello world!" - это массив, заданный в неявном виде непосредственно на месте использования.
    Скомпилируем код с ключом "-a" и посмотрим, что получилось:
      Открыть/закрыть
    Код:
    CODE 0	; 0
    ;program exit point
    	halt 0
    
    	proc	; main
    	; line 4
    	; line 5
    	push.c 0
    	;$par
    	push.c 4
    	sysreq.c 0	; print
    	stack 8
    	;$exp
    	; line 6
    	push.c 34
    	;$par
    	push.c 4
    	sysreq.c 0	; print
    	stack 8
    	;$exp
    	zero.pri
    	retn
    
    
    DATA 0	; 0
    dump 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0 48 65 6c 
    dump 6c 6f 20 77 6f 72 6c 64 21 0 
    
    STKSIZE 1000

    Обратите внимание на последовательность "48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0".
    Эта последовательность - ни что иное, как строка "Hello world!" и она повторяется в секции данных 2 раза.

    Проблему легко исправить, объявив строку в виде постоянного массива явным образом:
    PHP код:
    #include <a_samp>

    main()
    {
        static const 
    str_hello_world[] = "Hello world!";
        print(
    str_hello_world);
        print(
    str_hello_world);

    Проверим результат:
      Открыть/закрыть
    Код:
    CODE 0	; 0
    ;program exit point
    	halt 0
    
    	proc	; main
    	; line 4
    	; line 5
    	; line 6
    	push.c 0
    	;$par
    	push.c 4
    	sysreq.c 0	; print
    	stack 8
    	;$exp
    	; line 7
    	push.c 0
    	;$par
    	push.c 4
    	sysreq.c 0	; print
    	stack 8
    	;$exp
    	zero.pri
    	retn
    
    
    DATA 0	; 0
    dump 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0 
    
    STKSIZE 1000

    Заметьте, последовательность "48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0" не повторяется, а значит строка находится в секции данных всего в одном экземпляре.

    А теперь к практике: особенно часто можно заметить тот недостаток при использовании макросов.
    Пример:
    PHP код:
    #define SendNotAnAdminMsg(%0); SendClientMessage(%0, -1, "Вы не администратор!"); 
    Здесь создаётся не 1, не 2 копии строки, а ровно столько, сколько вы использовали его во всех командах, диалогах, etc.
    Исправляем:
    PHP код:
    static const __msg_not_an_admin[] = "Вы не администратор!";
    #define SendNotAnAdminMsg(%0); SendClientMessage(%0, -1, __msg_not_an_admin); 
    2 символа подчёркивания в начале названия массива - не более, чем перестраховка от его использования не по назначению (не из макроса).



    Упаковка строк.

    Возьмём для примера простой скрипт:
    PHP код:
    #include <a_samp>

    main()
    {
        print(
    "Hello world!");

    Возможно ли как-то оптимизировать этот код?
    Вполне, можно упаковать строку "Hello world!". На производительности это практически не отразится, но зато строки в упакованном виде будут занимать меньше места в памяти.
    Для упаковки строки достаточно лишь поставить перед ней знак "!":
    PHP код:
    #include <a_samp>

    main()
    {
        print(!
    "Hello world!");

    Для доказательства экономии сравним, во что скомпилируется код в обоих вариантах.
    Без упаковки строки:
      Открыть/закрыть
    Код:
    CODE 0	; 0
    ;program exit point
    	halt 0
    
    	proc	; main
    	; line 4
    	; line 5
    	push.c 0
    	;$par
    	push.c 4
    	sysreq.c 0	; print
    	stack 8
    	;$exp
    	zero.pri
    	retn
    
    
    DATA 0	; 0
    dump 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0 
    
    STKSIZE 1000

    С упаковкой строки:
      Открыть/закрыть
    Код:
    CODE 0	; 0
    ;program exit point
    	halt 0
    
    	proc	; main
    	; line 4
    	; line 5
    	push.c 0
    	;$par
    	push.c 4
    	sysreq.c 0	; print
    	stack 8
    	;$exp
    	zero.pri
    	retn
    
    
    DATA 0	; 0
    dump 48656c6c 6f20776f 726c6421 0 
    
    STKSIZE 1000

    Как можно заметить, содержимое секции кода в обоих вариантах полностью совпадает.
    Однако, в секции данных в первом варианте зарезервировано 13 ячеек: длина строки "Hello world!" - 12 символов, ещё 1 символ сигнализирует о завершении строки, при этом в неупакованном виде на каждый символ приходится по 1 ячейке.
    Во втором же варианте в секции данных всего 4 ячейки: 13/4 = 3+1 (13 не делится на 4 нацело, поэтому остаток размещается в дополнительной ячейке).
    В каждой ячейке могут вместиться 4 символа упакованной строки. Отсюда и экономия: упакованные строки занимают до 4 раз меньше места в памяти.
    Внимание: Функции format и printf не умеют правильно работать с упакованными строками (как в форматной строке, так и в форматируемых параметрах).
    Что не так уж и удивительно, если учесть, что к этим функциям прикасался куй.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  13. 2 пользователя(ей) сказали cпасибо:
    $continue$ (29.09.2015) Nurick (29.09.2015)
 

 
Страница 4 из 7 ПерваяПервая ... 2 3 4 5 6 ... ПоследняяПоследняя

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

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

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

Ваши права

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