Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 1 из 1
  1. #1
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

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

    Мифы о Pawn-скриптинге - #8

    Внимание: данная тема закрыта для защиты от копирования.
    Если есть какие-то вопросы, замечания или просто пожелания по поводу данного урока - оставляйте их здесь.


    Миф 8: "Если переменная принимает только значения 0/1 или true/false, лучше объявить её как bool, чтобы сэкономить память."

    Статус: Опровергнут.

    Описание:
    Этот миф, как и многие другие, изначально форсили на govno-info (и, судя по их целевой аудитории, миф этот оттуда никогда не исчезнет).
    Соль лишь в том, что Pawn сильно отличается от других Си-подобных языков и в нём нельзя задать размер переменной, отличный от 4 байт.

    Доказательство:
      Открыть/закрыть
    В Pawn размер данных обычно измеряется не в байтах, а в ячейках. В версии для SA:MP ячейка занимает 4 байта, но в других версиях её размер может быть равен 2 или 8 байтам.
    Типов данных, как таковых, в Pawn тоже нет (сам по себе интерпретатор умеет оперировать только целыми числами, а для вещественных введены нативные функции). Вместо них есть теги, которые были сделаны, чтобы было проще избежать ошибок при написании кода.
    Каждая переменная в Pawn занимает 4 байта (1 ячейку), независимо от её тега, поэтому если объявить переменную с тегом bool, её размер всё равно будет 4 байта.

    Докажем это на примере записи статуса авторизации у игроков.
    Сделаем два образца: в одном объявим массив без указания тега и будем записывать в него 1/0, а в другом укажем тег bool и будем записывать true/false.

    Образец 1:
    1. #include <a_samp>
    2.  
    3. new player_login_status[MAX_PLAYERS] = {0, ...};
    4.  
    5. public OnPlayerConnect(playerid)
    6. {
    7. player_login_status[playerid] = 1;
    8. }
    9.  
    10. public OnPlayerDisconnect(playerid, reason)
    11. {
    12. player_login_status[playerid] = 0;
    13. }


    Образец 2:
    1. #include <a_samp>
    2.  
    3. new bool:player_login_status[MAX_PLAYERS] = {false, ...};
    4.  
    5. public OnPlayerConnect(playerid)
    6. {
    7. player_login_status[playerid] = true;
    8. }
    9.  
    10. public OnPlayerDisconnect(playerid, reason)
    11. {
    12. player_login_status[playerid] = false;
    13. }


    Скомпилируем оба образца с ключами "-d0 -O1 -v2".
    Образец 1:
    Код:
    Header size:            140 bytes
    Code size:               92 bytes
    Data size:             4000 bytes
    Stack/heap size:      16384 bytes; estimated max. usage=9 cells (36 bytes)
    Total requirements:   20616 bytes
    Образец 2:
    Код:
    Header size:            140 bytes
    Code size:               92 bytes
    Data size:             4000 bytes
    Stack/heap size:      16384 bytes; estimated max. usage=9 cells (36 bytes)
    Total requirements:   20616 bytes
    Никаких различий. Тогда сравним ассемблерные листинги:
      Открыть/закрыть

    Образец 1:
    Код:
    CODE 0	; 0
    ;program exit point
    	halt 0
    
    
    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 
    
    CODE 0	; 8
    	proc	; OnPlayerConnect
    	; line 6
    	;$lcl playerid c
    	; line 7
    	zero.alt
    	load.s.pri c
    	idxaddr
    	move.alt
    	const.pri 1
    	stor.i
    	;$exp
    	zero.pri
    	retn
    
    	proc	; OnPlayerDisconnect
    	; line b
    	;$lcl reason 10
    	;$lcl playerid c
    	; line c
    	zero.alt
    	load.s.pri c
    	idxaddr
    	move.alt
    	zero.pri
    	stor.i
    	;$exp
    	zero.pri
    	retn
    
    
    STKSIZE 1000
    Образец 2:
    Код:
    CODE 0	; 0
    ;program exit point
    	halt 0
    
    
    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 
    
    CODE 0	; 8
    	proc	; OnPlayerConnect
    	; line 6
    	;$lcl playerid c
    	; line 7
    	zero.alt
    	load.s.pri c
    	idxaddr
    	move.alt
    	const.pri 1
    	stor.i
    	;$exp
    	zero.pri
    	retn
    
    	proc	; OnPlayerDisconnect
    	; line b
    	;$lcl reason 10
    	;$lcl playerid c
    	; line c
    	zero.alt
    	load.s.pri c
    	idxaddr
    	move.alt
    	zero.pri
    	stor.i
    	;$exp
    	zero.pri
    	retn
    
    
    STKSIZE 1000

    Содержимое листингов тоже совпадает, а значит что объявление переменных с тегом bool для записи true/false вместо 1/0 абсолютно никак не влияет на генерируемый код и не приводит к экономии памяти. Что и требовалось доказать.

    Тем не менее, можно сэкономить место в секции данных, если задать размер массива, используя оператор char.
    Этот оператор работает следующим образом: X char = (X+3)/4.
    Здесь 4 - кол-во байт в ячейке. Прибавление 3 сделано потому, что если просто разделить число на 4, то результат может оказаться неправильным. Например, для 6 char нельзя выделить полторы ячейки, нужно две.
    Для доступа к байтам вместо ячеек нужно использовать фигурные скобки вместо квадратных.
    1. #include <a_samp>
    2.  
    3. new player_login_status[MAX_PLAYERS char] = {0, ...};
    4.  
    5. public OnPlayerConnect(playerid)
    6. {
    7. player_login_status{playerid} = 1;
    8. }
    9.  
    10. public OnPlayerDisconnect(playerid, reason)
    11. {
    12. player_login_status{playerid} = 0;
    13. }

    Отчёт о компилцяии:
    Код:
    Header size:            140 bytes
    Code size:              116 bytes
    Data size:             1000 bytes
    Stack/heap size:      16384 bytes; estimated max. usage=9 cells (36 bytes)
    Total requirements:   17640 bytes
    Размер секции кода увеличился на 20 байт (для доступа к байтам используются другие инструкции, нежели для доступа к ячейкам), но зато в секции данных удалось сэкономить 3000 байт.


    Вывод: в Pawn нет типов данных, есть только теги, и если объявить переменную с тегом bool, она всё так же будет занимать 4 байта (1 ячейку).


    Специально для Pro-Pawn.ru
    Не разрешается копирование данной статьи на других ресурсах без разрешения автора.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  2. 13 пользователя(ей) сказали cпасибо:
    #NickName (23.02.2016) $continue$ (22.02.2016) Desulaid (22.02.2016) franked (24.02.2016) iWors (31.03.2016) L0ndl3m (22.02.2016) Lombardo (14.05.2016) Profyan (22.02.2016) Prolific (17.03.2016) vovandolg (22.02.2016) VVWVV (22.02.2016) [ForD] (22.02.2016) _lizard (05.08.2016)
 

 

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

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

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

Ваши права

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