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

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

    Упакованные строки

    Всем привет.

    Сегодня хотелось бы обсудить с вами ещё один приём для оптимизации кода на Pawn, с которым сейчас мало кто знаком: упаковывание строк. Этот приём не повлияет на производительность работы сервера, но в некоторых ситуациях может здорово помочь сэкономить память.
    Дело в том, что по умолчанию компилятор Pawn хранит все строки по принципу "один символ на ячейку".
    В версии Pawn для SA-MP ячейка имеет размер в 4 байта, поэтому строки хранятся в четырёхбайтовой кодировке - для хранения символа используется только один байт из четырёх, а остальные три просто расходуются впустую (они всегда заполнены нулями).
    PHP код:
    new const unpacked_string[] = "Sample text"// 1 ячейка на символ -> 12 ячеек -> 48 байт 
    Тем не менее, в Pawn есть возможность избежать подобной растраты. Строки можно хранить в упакованном формате, в котором для каждого символа отводится не целая ячейка (4 байта), а лишь 1 байт. В таком формате строки занимают примерно в 4 раза меньше памяти, чем неупакованные строки.
    Чтобы строка стала упакованной, нужно всего лишь поставить перед ней восклицательный знак.
    PHP код:
    new const packed_string[] = !"Sample text"// 1 байт на символ - 12 байт (48 - 12 = 36 байт сэкономлено) 
    Также можно делать массивы из упакованных строк (т.е. двухмерные массивы):
    PHP код:
    new const faction_names[6][] =
    {
        {!
    "Нет"},
        {!
    "Полиция"},
        {!
    "ФСБ"},
        {!
    "Армия"},
        {!
    "МЧС"},
        {!
    "Мэрия"}
    }; 

    Знак "!" не является оператором, это всего лишь часть синтаксиса объявления упакованных строк, он работает только со строками, объявленными в кавычках.
    Если вы хотите упаковать строку, которая уже объявлена в виде массива, то с помощью знака "!" у вас ничего не получится.
    PHP код:
    new const unpacked_string[] = "Sample text";
    new const 
    packed_string[] = !unpacked_string// Ошибка 
    Для работы с упакованными строками есть специальные функции:
    PHP код:
    // Упаковывает строку source в массив dest с размером maxlength
    native strpack(dest[], const source[], maxlength=sizeof dest);

    // Распаковывает строку source в массив dest
    native strunpack(dest[], const source[], maxlength=sizeof dest); 
    Следует заметить, что другие функции из string.inc умеют работать с упакованными строками.
    Рассмотрим эту особенность на примере strcat:
    PHP код:
    native strcat(dest[], const source[], maxlength=sizeof dest); 
    Если строка dest упакована, а source нет, то функция будет копировать символы из source и "на лету" упаковывать их перед записью в dest.
    Примерно то же самое произойдёт, если с помощью strcat добавить упакованную строку к неупакованной.
    PHP код:
    // Сцепляем две строки.
    new str[32] = !"string1";
    new 
    unpacked_string[] = "string2";
    strcat(strunpacked_string);

    // Будет выведено "string1string2".
    print(str); 
    Кроме функций из string.inc многие функции SA-MP также "понимают" упакованные строки.


    Также следует иметь в виду, что некоторые функции не поддерживают работу с упакованными строками или работают с ними не во всех случаях:
    • printf, format - эти функции сделал сам Kalcor (что уже говорит о том, что в них должно быть что-то нерабочее и это что-то никогда не будет исправлено потому что "владельцы крупных серверов решают всё за него").
      В этих функциях упакованные строки не поддерживаются ни в форматной строке, ни в последующих аргументах.
    • fwrite - также не поддерживает упакованные строки.
    • ispacked - возвращает 0, если упакованная строка начинается с символа, код которого больше 127.

    Если строка, которую вы хотите упаковать, используется в одной из перечисленных выше функций, её следует оставить неупакованной.


    Собственно, это всё, что я помню про упакованные строки. Если вы думаете, что я что-то забыл, или у вас просто есть вопрос, буду рад услышать вас в комментариях.


    Автор: Daniel_Cortez

    Специально для Pro-Pawn.ru
    Копирование данной статьи на других ресурсах без разрешения автора запрещено!
    Последний раз редактировалось Daniel_Cortez; 19.06.2016 в 21:22. Причина: -
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  2. 18 пользователя(ей) сказали cпасибо:
    $continue$ (19.06.2016) Astrakhan30 (23.06.2016) BadPawn (20.06.2016) Desulaid (19.06.2016) Duck_Leo (16.05.2021) Found (19.06.2016) iWors (28.07.2016) kushichka (25.06.2016) nikvlad (19.06.2016) Nurick (20.06.2016) Profyan (26.06.2016) Redsan (21.06.2016) Sarah (25.07.2019) TheMallard (20.06.2016) Unreal (19.06.2016) vovandolg (26.07.2016) [ForD] (23.06.2016) _lizard (07.08.2016)
  3. #2
    Аватар для nikvlad
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.02.2016
    Сообщений
    94
    Репутация:
    2 ±
    Цитата Сообщение от Daniel_Cortez
    // Будет выведено "string1string2". Я бы использовал print/printf для простоты, но нельзя (см. ниже).

    Только что попробовал вывести с помощью print, все прекрасно вывело.

  4. Пользователь сказал cпасибо:
    Daniel_Cortez (19.06.2016)
  5. #3
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от nikvlad Посмотреть сообщение
    Только что попробовал вывести с помощью print, все прекрасно вывело.
    Да, верно. Совсем вылетело из головы, что с упакованными строками не работает только printf. 12 ночи, что ещё сказать -_-

    Исправил пример.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  6. Пользователь сказал cпасибо:
    nikvlad (19.06.2016)
  7. #4
    Аватар для Unreal
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.09.2014
    Сообщений
    133
    Репутация:
    4 ±
    а можно по поподробнее о
    PHP код:
    // Упаковывает строку source в массив dest с размером maxlength
    native strpack(dest[], const source[], maxlength=sizeof dest);

    // Распаковывает строку source в массив dest
    native strunpack(dest[], const source[], maxlength=sizeof dest); 
    и пару примеров пожалуйста
    Pro-pawn.ru

  8. #5
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Тут информация проскочила, что strpack не дружит с русскими символами. Точнее, если при запаковке первый символ русский, ispacked вернёт 0 при проверке запакованного массива
    PHP код:
    new string[8 char];
    strpack(string"Привет");
    printf("%d"ispacked(string)); 
    Стоит добавить хоть один английский символ
    PHP код:
    new string[8 char];
    strpack(string"qПривет");
    printf("%d"ispacked(string)); 
    И всё отображает нормально + при распаковке так же все символы сохраняются
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

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

    Статус
    Оффлайн
    Регистрация
    15.03.2015
    Адрес
    Slobodskoy
    Сообщений
    667
    Репутация:
    236 ±
    Цитата Сообщение от Unreal Посмотреть сообщение
    а можно по поподробнее о
    PHP код:
    // Упаковывает строку source в массив dest с размером maxlength
    native strpack(dest[], const source[], maxlength=sizeof dest);

    // Распаковывает строку source в массив dest
    native strunpack(dest[], const source[], maxlength=sizeof dest); 
    и пару примеров пожалуйста
    Все функции есть на wiki.sa-mp.com, с примера и характеристиками аргументов функции!

  10. #7
    Аватар для m1n1vv
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Сообщений
    541
    Репутация:
    78 ±
    А можно как-то объединить упакованную строку, например с описанием чего-то, и простую строку string с полученными данными с format'а?
    Последний раз редактировалось m1n1vv; 21.06.2016 в 06:46.

  11. #8
    Аватар для Found
    G

    Статус
    Оффлайн
    Регистрация
    18.05.2016
    Адрес
    041b0438043f04
    Сообщений
    35
    Репутация:
    9 ±
    Цитата Сообщение от m1n1vv Посмотреть сообщение
    А можно как-то объединить упакованную строку, например с описанием чего-то, и простую строку string с полученными данными с format'а?
    Если я Вас правильно понял, то подобный пример уже приводится в статье.
    PHP код:
    // Сцепляем две строки.
    new str[32] = !"string1";
    new 
    unpacked_string[] = "string2";
    strcat(strunpacked_string);

    // Будет выведено "string1string2".
    print(str); 
    Последний раз редактировалось Found; 21.06.2016 в 20:35.

  12. #9
    Аватар для m1n1vv
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Сообщений
    541
    Репутация:
    78 ±
    Цитата Сообщение от Found Посмотреть сообщение
    Если я Вас правильно понял, то подобный пример уже приводится в статье.
    PHP код:
    // Сцепляем две строки.
    new str[32] = !"string1";
    new 
    unpacked_string[] = "string2";
    strcat(strunpacked_string);

    // Будет выведено "string1string2".
    print(str); 

    Как я понял, будет типа такого?
    PHP код:
    new str[32] = !"Какое-то сообщение";
    new 
    string[32];
    format(stringsizeof string"Город: %s"city);
    strcat(strstring); //...
    print(str); 

  13. #10
    Аватар для Found
    G

    Статус
    Оффлайн
    Регистрация
    18.05.2016
    Адрес
    041b0438043f04
    Сообщений
    35
    Репутация:
    9 ±
    Цитата Сообщение от m1n1vv Посмотреть сообщение
    Как я понял, будет типа такого?
    PHP код:
    new str[32] = !"Какое-то сообщение";
    new 
    string[32];
    format(stringsizeof string"Город: %s"city);
    strcat(strstring); //...
    print(str); 
    Именно так.

 

 
Страница 1 из 5 1 2 3 ... ПоследняяПоследняя

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

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

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

Ваши права

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