PDA

Просмотр полной версии : [Урок] Упакованные строки



Daniel_Cortez
19.06.2016, 20:46
Всем привет.

Сегодня хотелось бы обсудить с вами ещё один приём для оптимизации кода на Pawn, с которым сейчас мало кто знаком: упаковывание строк. Этот приём не повлияет на производительность работы сервера, но в некоторых ситуациях может здорово помочь сэкономить память.
Дело в том, что по умолчанию компилятор Pawn хранит все строки по принципу "один символ на ячейку".
В версии Pawn для SA-MP ячейка имеет размер в 4 байта, поэтому строки хранятся в четырёхбайтовой кодировке - для хранения символа используется только один байт из четырёх, а остальные три просто расходуются впустую (они всегда заполнены нулями).


new const unpacked_string[] = "Sample text"; // 1 ячейка на символ -> 12 ячеек -> 48 байт

Тем не менее, в Pawn есть возможность избежать подобной растраты. Строки можно хранить в упакованном формате, в котором для каждого символа отводится не целая ячейка (4 байта), а лишь 1 байт. В таком формате строки занимают примерно в 4 раза меньше памяти, чем неупакованные строки.
Чтобы строка стала упакованной, нужно всего лишь поставить перед ней восклицательный знак.


new const packed_string[] = !"Sample text"; // 1 байт на символ - 12 байт (48 - 12 = 36 байт сэкономлено)

Также можно делать массивы из упакованных строк (т.е. двухмерные массивы):


new const faction_names[6][] =
{
{!"Нет"},
{!"Полиция"},
{!"ФСБ"},
{!"Армия"},
{!"МЧС"},
{!"Мэрия"}
};



Знак "!" не является оператором, это всего лишь часть синтаксиса объявления упакованных строк, он работает только со строками, объявленными в кавычках.
Если вы хотите упаковать строку, которая уже объявлена в виде массива, то с помощью знака "!" у вас ничего не получится.


new const unpacked_string[] = "Sample text";
new const packed_string[] = !unpacked_string; // Ошибка


Для работы с упакованными строками есть специальные функции:


// Упаковывает строку source в массив dest с размером maxlength
native strpack(dest[], const source[], maxlength=sizeof dest);

// Распаковывает строку source в массив dest
native strunpack(dest[], const source[], maxlength=sizeof dest);


Следует заметить, что другие функции из string.inc умеют работать с упакованными строками.
Рассмотрим эту особенность на примере strcat:


native strcat(dest[], const source[], maxlength=sizeof dest);

Если строка dest упакована, а source нет, то функция будет копировать символы из source и "на лету" упаковывать их перед записью в dest.
Примерно то же самое произойдёт, если с помощью strcat добавить упакованную строку к неупакованной.


// Сцепляем две строки.
new str[32] = !"string1";
new unpacked_string[] = "string2";
strcat(str, unpacked_string);

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

Кроме функций из string.inc многие функции SA-MP также "понимают" упакованные строки.


Также следует иметь в виду, что некоторые функции не поддерживают работу с упакованными строками или работают с ними не во всех случаях:

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

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


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


Автор: Daniel_Cortez (http://pro-pawn.ru/member.php?100-Daniel_Cortez)


Специально для Pro-Pawn.ru (http://www.pro-pawn.ru)
Копирование данной статьи на других ресурсах без разрешения автора запрещено!

nikvlad
19.06.2016, 21:10
// Будет выведено "string1string2". Я бы использовал print/printf для простоты, но нельзя (см. ниже).



Только что попробовал вывести с помощью print, все прекрасно вывело.
http://dl1.joxi.net/drive/2016/06/19/0004/1911/292727/27/4e624b1dcd.jpg

Daniel_Cortez
19.06.2016, 21:26
Только что попробовал вывести с помощью print, все прекрасно вывело.
http://dl1.joxi.net/drive/2016/06/19/0004/1911/292727/27/4e624b1dcd.jpg
Да, верно. Совсем вылетело из головы, что с упакованными строками не работает только printf. 12 ночи, что ещё сказать -_-

Исправил пример.

Unreal
19.06.2016, 22:48
а можно по поподробнее о

// Упаковывает строку source в массив dest с размером maxlength
native strpack(dest[], const source[], maxlength=sizeof dest);

// Распаковывает строку source в массив dest
native strunpack(dest[], const source[], maxlength=sizeof dest);

и пару примеров пожалуйста

DeimoS
19.06.2016, 23:40
Тут информация проскочила, что strpack не дружит с русскими символами. Точнее, если при запаковке первый символ русский, ispacked вернёт 0 при проверке запакованного массива

new string[8 char];
strpack(string, "Привет");
printf("%d", ispacked(string));
Стоит добавить хоть один английский символ

new string[8 char];
strpack(string, "qПривет");
printf("%d", ispacked(string));
И всё отображает нормально + при распаковке так же все символы сохраняются

Desulaid
20.06.2016, 03:24
а можно по поподробнее о

// Упаковывает строку 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, с примера и характеристиками аргументов функции!

m1n1vv
21.06.2016, 06:40
А можно как-то объединить упакованную строку, например с описанием чего-то, и простую строку string с полученными данными с format'а?

Found
21.06.2016, 18:16
А можно как-то объединить упакованную строку, например с описанием чего-то, и простую строку string с полученными данными с format'а?
Если я Вас правильно понял, то подобный пример уже приводится в статье.


// Сцепляем две строки.
new str[32] = !"string1";
new unpacked_string[] = "string2";
strcat(str, unpacked_string);

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

m1n1vv
22.06.2016, 09:47
Если я Вас правильно понял, то подобный пример уже приводится в статье.


// Сцепляем две строки.
new str[32] = !"string1";
new unpacked_string[] = "string2";
strcat(str, unpacked_string);

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



Как я понял, будет типа такого?

new str[32] = !"Какое-то сообщение";
new string[32];
format(string, sizeof string, "Город: %s", city);
strcat(str, string); //...
print(str);

Found
22.06.2016, 12:38
Как я понял, будет типа такого?

new str[32] = !"Какое-то сообщение";
new string[32];
format(string, sizeof string, "Город: %s", city);
strcat(str, string); //...
print(str);

Именно так.

SlimX
22.06.2016, 14:22
А как с динамическими текстами быть, допустим, объявления в News?

TheMallard
22.06.2016, 15:22
format не работает с упакованными строками! Читайте внимательней!

#Johnson
22.06.2016, 15:25
Так можно?

new BizzInfo[MAX_BIZZ][bInfo] = {
{0,!"The State","No-one", !"City Bank", -828.0927,1503.2441,19.6667, 1,2147.9228,1603.7501,1006.1677, 999000000,50,0,100,100,99984,15,500,205}
};

m1n1vv
22.06.2016, 17:37
Так можно?

new BizzInfo[MAX_BIZZ][bInfo] = {
{0,!"The State","No-one", !"City Bank", -828.0927,1503.2441,19.6667, 1,2147.9228,1603.7501,1006.1677, 999000000,50,0,100,100,99984,15,500,205}
};

Нет, компилятор потребует указать тег Float к переменной

VVWVV
22.06.2016, 20:09
- Данный способ не оптимизирует код, он лишь сокращает потребление сегмента данных, что способствует уменьшению размера файла. Возможно существует какая-то оптимизация, которая, может быть, увеличивает скорость выполнения кода, но это, как минимум, только лишь микросекунды.
- Кстати, в данной теме нет упоминания об обращении к элементу массива.

Nash_Brigers
22.06.2016, 20:39
Del

Daniel_Cortez
23.06.2016, 00:41
А можно как-то объединить упакованную строку, например с описанием чего-то, и простую строку string с полученными данными с format'а?
Вы не читали статью до конца, так ведь?




Так можно?

new BizzInfo[MAX_BIZZ] = {
{0,!"The State","No-one", !"City Bank", -828.0927,1503.2441,19.6667, 1,2147.9228,1603.7501,1006.1677, 999000000,50,0,100,100,99984,15,500,205}
};
Нет, я запрещаю.
Разве это так трудно проверить самостоятельно?




- Данный способ не оптимизирует код, он лишь сокращает потребление сегмента данных, что способствует уменьшению размера файла. Возможно существует какая-то оптимизация, которая, может быть, увеличивает скорость выполнения кода, но это, как минимум, только лишь микросекунды.
Советую ознакомиться со значением понятия оптимизации в информатике (https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)) - это не только улучшение производительности.


- Кстати, в данной теме нет упоминания об обращении к элементу массива.
http://pro-pawn.ru/showthread.php?13706




А как с динамическими текстами быть, допустим, объявления в News?
Смотря, как устроен вывод этих объявлений. Если текст объявления выводится непосредственно в момент его подачи игроком (например, прямо в команде /ad - ну или какая у вас там команда?), то нет смысла упаковывать текст, под который сервер и без того выделяет память в секции стека/кучи.
Другое дело, если тексты объявлений хранятся в каком-нибудь массиве строк, ожидая момента подачи в эфир (например, если сообщения перед выводом в эфир должны проходить проверку [s]цензором модератором).
Примерно так должен будет выглядеть массив для сообщений:


const MAX_AD_MESSAGES = 8;
const MAX_AD_MESSAGE_TEXT = 128;
new ad_messages[MAX_AD_MESSAGES][MAX_AD_MESSAGE_TEXT + 1];
new free_ad_message_slot = 0; // Здесь будет храниться номер слота, в который запишется очередное сообщение.
// При записи сообщения free_ad_message_slot увеличивается на 1. Если free_ad_message_slot больше или равно MAX_AD_MESSAGES,
// игроку выводится текст "слишком много сообщений в очереди, попробуйте позже".

В секции данных выделится 129*8=1032 ячеек. Здесь уже есть смысл сократить размер последнего измерения массива и записывать в него упакованные строки.


new ad_messages[MAX_AD_MESSAGES][(MAX_AD_MESSAGE_TEXT + 1) char];

В этом случае будет выделено всего 33*8=264 ячейки. Сохранение сообщений можно сделать с помощью strpack.


CMD:ad(playerid, params[])
{
// ...
strpack(ad_messages[free_ad_message_slot++], params, MAX_AD_MESSAGE_TEXT);
// ...
}





Тут информация проскочила, что strpack не дружит с русскими символами. Точнее, если при запаковке первый символ русский, ispacked вернёт 0 при проверке запакованного массива

new string[8 char];
strpack(string, "Привет");
printf("%d", ispacked(string));
Стоит добавить хоть один английский символ

new string[8 char];
strpack(string, "qПривет");
printf("%d", ispacked(string));
И всё отображает нормально + при распаковке так же все символы сохраняются
С функцией strpack тут всё в порядке, строка упаковывается правильно (в чём можно убедиться, логируя содержимое каждого байта в массиве string), проблема именно в ispacked.

Но всё же хотелось бы знать: откуда эта "информация проскочила"?
Я проверил на последней версии Pawn (4.0), там этот баг тоже есть. Можно сообщить о нём разработчику, но желательно будет упомянуть в багрепорте, кто изначально нашел баг, чтобы это не выглядело, как присвоение чужой находки. До этого я уже сообщал подобным образом о баге в strins (https://github.com/compuphase/pawn/issues/15).
Не то, чтобы это волшебным образом исправит баг в SA-MP (обновление до новой версии Pawn вряд ли вписывается в график стагнации мультиплеера), но... наверняка кто-нибудь другой пользуется Pawn 4.0 для проектов, не связанных с SA-MP.

Nurick
29.06.2016, 00:22
Доброй ночи!
Можно задам вопрос, у меня 2 примера.

В 1 примере я могу использовать упакованные строки:

new string[] = !"текст",
string_1[] = !"текст",
string_2[] = !"текст";

string[sizeof( string ) -1] = '\n';
string_1[sizeof( string_1 ) -1] = '\n';
string_2[sizeof( string_2 ) -1] = '\0';

ShowPlayerDialog( playerid, 0, DIALOG_STYLE_MSGBOX, "Текст", string, "1", "2" );

А во 2 примере НЕТ так как используется format:

static const string[] = !"%s\nтекст";
new str[sizeof( string ) + ( -2 + MAX_PLAYER_NAME ) +1];

format( str, sizeof( str ), string, Player[playerid][Username] );
ShowPlayerDialog( playerid, 0, DIALOG_STYLE_INPUT, "Текст", string, "1", "2" );

Правильно понял?

Desulaid
29.06.2016, 01:33
Nurick, да. А первый пример можно сделать проще и без магии.


static string[] =
{
!"тут такой страшный и большой текст\n\
которого у меня, к сожалению, нет.\n\
поэтому я пищу этот бред"
};
ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, !"текст", string, !"1", !"2");

Nurick
29.06.2016, 12:03
В твоём случае будет ошибка error 075: input line too long (входная строка слишком длинная), за это я использовал связку строк

VVWVV
29.06.2016, 12:29
В твоём случае будет ошибка error 075: input line too long (входная строка слишком длинная), за это я использовал связку строк

Можно ещё так:

new buffer[] = "test1"\
"test3";
printf("%s", buffer);

Desulaid
29.06.2016, 12:34
В твоём случае будет ошибка error 075: input line too long (входная строка слишком длинная), за это я использовал связку строк

Компилятор от Zeex используй. Там исправлен такой баг или вот этот (http://pro-pawn.ru/showthread.php?3586-%D0%A0%D1%83%D1%81%D0%B8%D1%84%D0%B8%D1%86%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%82%D0%BE%D1%80-Pawn) используй :3

Nurick
29.06.2016, 14:09
Задам глупый вопрос тут же, скачиваю содержимое Zeex/pawn (https://github.com/Zeex/pawn) далее распаковать файл в содержимое gamemode/pawno?? и открывать стандартным pawno?

Daniel_Cortez
29.06.2016, 14:22
В 1 примере я могу использовать упакованные строки:

new string[] = !"текст",
string_1[] = !"текст",
string_2[] = !"текст";

string[sizeof( string ) -1] = '\n';
string_1[sizeof( string_1 ) -1] = '\n';
string_2[sizeof( string_2 ) -1] = '\0';

ShowPlayerDialog( playerid, 0, DIALOG_STYLE_MSGBOX, "Текст", string, "1", "2" );

Не совсем корректно. Я бы расписал сейчас, в чём дело, но будет слишком много теории для одного ответа.
Попробую сегодня-завтра добавить в статью похожий пример.
И да, выбросите уже Pawno и найдите нормальный редактор, который не подсовывает пробелы посреди табов.




А во 2 примере НЕТ так как используется format:

static const string[] = !"%s\nтекст";
new str[sizeof( string ) + ( -2 + MAX_PLAYER_NAME ) +1];

format( str, sizeof( str ), string, Player[playerid][Username] );
ShowPlayerDialog( playerid, 0, DIALOG_STYLE_INPUT, "Текст", string, "1", "2" );

Правильно понял?
Да, здесь ничего упаковывать не следует.



Задам глупый вопрос тут же, скачиваю содержимое Zeex/pawn (https://github.com/Zeex/pawn) далее распаковать файл в содержимое gamemode/pawno?? и открывать стандартным pawno?
Это исходники компилятора. Сборки можно скачать здесь (https://ci.appveyor.com/project/Zeex/pawn/branch/master/artifacts).

Nurick
29.06.2016, 14:42
Спасибо всем!

Desulaid
30.06.2016, 00:24
Тут информация проскочила, что strpack не дружит с русскими символами. Точнее, если при запаковке первый символ русский, ispacked вернёт 0 при проверке запакованного массива

new string[8 char];
strpack(string, "Привет");
printf("%d", ispacked(string));
Стоит добавить хоть один английский символ

new string[8 char];
strpack(string, "qПривет");
printf("%d", ispacked(string));
И всё отображает нормально + при распаковке так же все символы сохраняются

Проблема была в ispacked. Я так это пофиксил.


stock ispacked_fix(const string[])
{
if ((string[0] >> 24) == 0)
return 0;
return 1;
}
#if defined _ALS_ispacked
#undef ispacked
#else
#define _ALS_ispacked
#endif
#define ispacked ispacked_fix

Nexius_Tailer
30.06.2016, 01:02
И да, выбросите уже Pawno и найдите нормальный редактор, который не подсовывает пробелы посреди табов.
Павно удобен для лёгких скриптов, особенно если писать всё в одном файле. Поэтому тут уж зависит от желания скриптера.

Nurick
30.06.2016, 22:23
Подниму еще раз данную тему, еще появился один вопрос.

Создаю глобальную переменную

static const authorization_string[] = "%s";
new authorization_str[sizeof( authorization_string ) + ( -2 + MAX_PLAYER_NAME ) +1];

Далее её использую

format( authorization_str, sizeof( authorization_str ), authorization_string, Player[playerid][Username] );
ShowPlayerDialog( playerid, 2, DIALOG_STYLE_PASSWORD, !"Авторизация", authorization_str, !"Войти", !"Отмена" );

Суть вопроса при этом я могу упаковать ShowPlayerDialog !"Заголовок" !"Кнопка 1" !"Кнопка 2" ?

$continue$
30.06.2016, 23:41
А, скомпилировать?) А, проверить?)

Подниму еще раз данную тему, еще появился один вопрос.

Создаю глобальную переменную

static const authorization_string[] = "%s";
new authorization_str[sizeof( authorization_string ) + ( -2 + MAX_PLAYER_NAME ) +1];

Далее её использую

format( authorization_str, sizeof( authorization_str ), authorization_string, Player[playerid][Username] );
ShowPlayerDialog( playerid, 2, DIALOG_STYLE_PASSWORD, !"Авторизация", authorization_str, !"Войти", !"Отмена" );

Суть вопроса при этом я могу упаковать ShowPlayerDialog !"Заголовок" !"Кнопка 1" !"Кнопка 2" ?

Nurick
01.07.2016, 01:50
А знающему человеку трудно ответить ДА или НЕТ?! И да знал бы я как проверить я бы не задавался этим вопросом.
Можно задам тебе встречный вопрос? Для чего существуют различные форумы?

VVWVV
01.07.2016, 04:21
Подниму еще раз данную тему, еще появился один вопрос.

Создаю глобальную переменную

static const authorization_string[] = "%s";
new authorization_str[sizeof( authorization_string ) + ( -2 + MAX_PLAYER_NAME ) +1];

Далее её использую

format( authorization_str, sizeof( authorization_str ), authorization_string, Player[playerid][Username] );
ShowPlayerDialog( playerid, 2, DIALOG_STYLE_PASSWORD, !"Авторизация", authorization_str, !"Войти", !"Отмена" );

Суть вопроса при этом я могу упаковать ShowPlayerDialog !"Заголовок" !"Кнопка 1" !"Кнопка 2" ?

Да, можете.

$continue$
01.07.2016, 12:19
Так, а почему проверить нельзя? Я понимаю если бы ты 1 день был в сфере скриптинга, но ты больше года же тут?

А знающему человеку трудно ответить ДА или НЕТ?!
Так, берешь нажимаешь в Pawno -> new.pwn -> создаешь диалог с упаковкой строки и пробуешь. В чем проблема?

И да знал бы я как проверить я бы не задавался этим вопросом.
Разная тематика форумов. К чему этот вопрос?

Можно задам тебе встречный вопрос? Для чего существуют различные форумы?

Nurick
01.07.2016, 16:38
Так я и с помощью формата смогу скомпилировать упакованную строку, хотя это никак работать не будет, за это и спрашивал об этом как, ну тогда будь добр объясни мне пожалуйста как проверить сэкономлено было байтов или нет

VVWVV
01.07.2016, 23:06
как проверить сэкономлено было байтов или нет

Сегмент данных будет в несколько раз меньше. Используй флаг -v2 для вывода подобной информации.

DeimoS
04.07.2016, 15:14
Но всё же хотелось бы знать: откуда эта "информация проскочила"?
Я проверил на последней версии Pawn (4.0), там этот баг тоже есть. Можно сообщить о нём разработчику, но желательно будет упомянуть в багрепорте, кто изначально нашел баг, чтобы это не выглядело, как присвоение чужой находки. До этого я уже сообщал подобным образом о баге в strins (https://github.com/compuphase/pawn/issues/15).
Не то, чтобы это волшебным образом исправит баг в SA-MP (обновление до новой версии Pawn вряд ли вписывается в график стагнации мультиплеера), но... наверняка кто-нибудь другой пользуется Pawn 4.0 для проектов, не связанных с SA-MP.

Некий Anton Styazhkin, который сам уже замутил костыль исправление этого бага.

Duck_Leo
16.05.2021, 02:37
Честно говоря удивлён был, но размер .amx реал уменьшился при использования запаковки строки:
ShowFallVehicle(playerid)
{
ShowPlayerDialog
(
playerid, dialogid_fallveh, DIALOG_STYLE_LIST,

"Падение с мото и вело транспорта",

(!fallveh_active[playerid])
? (!"Запретить падать\nРазрешить падать {00ff00}[выбрано]")
: (!"Запретить падать {00ff00}[выбрано]\n{ffffff}Разрешить падать"),

"Выбор", "Назад"
);
}
Был: 712 КБ (729 884 байт)
Стал: 712 КБ (729 813 байт)

В планах есть изменить везде где только можно на упакованные строки в моде, но надеюсь это не приведёт к худшему)

Shaolinka
16.05.2021, 02:47
Честно говоря удивлён был, но размер .amx реал уменьшился при использования запаковки строки:
ShowFallVehicle(playerid)
{
ShowPlayerDialog
(
playerid, dialogid_fallveh, DIALOG_STYLE_LIST,

"Падение с мото и вело транспорта",

(!fallveh_active[playerid])
? (!"Запретить падать\nРазрешить падать {00ff00}[выбрано]")
: (!"Запретить падать {00ff00}[выбрано]\n{ffffff}Разрешить падать"),

"Выбор", "Назад"
);
}
Был: 712 КБ (729 884 байт)
Стал: 712 КБ (729 813 байт)

В планах есть изменить везде где только можно на упакованные строки в моде, но надеюсь это не приведёт к худшему)

Стал бы упаковывать лишь огромный string(от 500 символов и дальше), имхо. Везде не получится же, упаковав формаченный стринг, кракозябры в ответ, поэтому тут strpack, в прочем об этом и так есть в этой теме.

Duck_Leo
16.05.2021, 03:20
Shaolinka да. Но нужно быть аккуратным. Я вот щас мельком глянул исходники мода где есть строки, и в некоторых случаях format есть

DeimoS
17.05.2021, 07:37
В планах есть изменить везде где только можно на упакованные строки в моде, но надеюсь это не приведёт к худшему)

А зачем? Какую проблему ты этим собрался решить?

Duck_Leo
17.05.2021, 13:23
А зачем? Какую проблему ты этим собрался решить?

Ну почему бы не воспользоваться такой возможностью. Но в тоже время не понятно в чём выигрыш от запаковки строк? Ваши мнения

Shaolinka
17.05.2021, 15:15
Ну почему бы не воспользоваться такой возможностью. Но в тоже время не понятно в чём выигрыш от запаковки строк? Ваши мнения

Выигрыш в том, что вместо 4 байт на символ будет использоваться 1, об этом собственно написано в этой теме. Но зачем каждый раз упаковывать, особенно не большой стринг, от этого твой сервер быстрее/медленнее работать не станет. Если перфекционист, то упаковывай всё подряд.

DeimoS
17.05.2021, 16:50
Ну почему бы не воспользоваться такой возможностью.

Например, затем, чтоб не тратить своё время на то, что не будет решать какой-то проблемы, а значит и не принесёт никакой пользы? Если ты потратишь это же время на то, чтоб придумывать и реализовывать какие-то интересные системы - игроки тебе будут более благодарны, нежели если твой мод станет весить на пару килобайт меньше (чему никто особо благодарен не будет).

Про упаковку строк можно почитать просто как про "забавную" возможность языка. Но всерьёз заниматься подобной оптимизацией памяти - глупо. Для SAMP-серверов не существует такой проблемы, как нехватка памяти для запуска сервера. Поэтому и целенаправленно что-то упаковывать нет никакого смысла: ты от этого только потеряешь в оптимизации, если тебе, перед использованием текста, придётся его распаковывать.
Максимум, можно взять за привычку тему с упаковкой и упаковывать строки в новом коде, но, опять же, практического смысла в этом 0, а лишние телодвижения вся эта упаковка делать заставит (как минимум, добавлять лишний восклицательный знак в код, при этом, следя за тем, чтоб не добавить его там, где упаковка строки может сломать код).

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


Выигрыш в том, что вместо 4 байт на символ будет использоваться 1, об этом собственно написано в этой теме. Но зачем каждый раз упаковывать, особенно не большой стринг, от этого твой сервер быстрее/медленнее работать не станет. Если перфекционист, то упаковывай всё подряд.

ИМХО, но даже для какого-то большого объёма текста упаковка строк носит, скорее, символический характер, нежели приносит реальную пользу для сервера. Тем более, что если текст придётся распаковать перед использованием - для его хранения всё равно придётся выделить полноценное количество памяти из стека.