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

Реклама


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

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

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

    Всем привет.

    Сегодня хотелось бы обсудить с вами ещё один приём для оптимизации кода на 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 - также не поддерживает упакованные строки. Скорее всего, это опять же связано с вмешательством Kalcor'а, поскольку в интерпретаторе Pawn 3.0 (а именно эта версия интерпретатора используется в SA-MP в сочетании с компилятором от версии 3.2) такого бага не наблюдается.
    • ispacked - возвращает 0, если упакованная строка начинается с символа, код которого больше 127.

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


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


    Автор: Daniel_Cortez

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

  2. 16 пользователя(ей) сказали cпасибо:
    $continue$ (19.06.2016)Astrakhan30 (23.06.2016)BadPawn (20.06.2016)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)TheMallard (20.06.2016)Unreal (19.06.2016)untonyst (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
    new fuck_logic[0] = EOS;

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

    Исправил пример.
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

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

    Статус
    Оффлайн
    Регистрация
    24.09.2014
    Сообщений
    116
    Репутация:
    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
    Адрес
    Восточный Мордор
    Сообщений
    3,931
    Репутация:
    1502 ±
    Тут информация проскочила, что 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)); 
    И всё отображает нормально + при распаковке так же все символы сохраняются
    Связаться со мной можно в личных сообщениях этой группы

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

    Steve Pavlina

  9. #6
    Аватар для untonyst
    Младший сержант

    Статус
    Оффлайн
    Регистрация
    15.03.2015
    Адрес
    Slobodskoy
    Сообщений
    663
    Репутация:
    234 ±
    Цитата Сообщение от 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, с примера и характеристиками аргументов функции!
    Младший сержант Стяжкин | ЧСВ группа в ВКонтакте NEW

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

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Сообщений
    307
    Репутация:
    34 ±
    А можно как-то объединить упакованную строку, например с описанием чего-то, и простую строку 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
    Сообщений
    307
    Репутация:
    34 ±
    Цитата Сообщение от 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 из 4 123 ... ПоследняяПоследняя

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

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

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

Ваши права

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