Просмотр полной версии : [Вопрос] стринги
John_Smith (Scripter)
16.03.2015, 02:30
Всем привет, я с одним знакомым долго спорил что лучше использовать 1 глобальный стринг для каждого игрока с максимальным размером или же создавать разные стринги с разными размерами в разных пабликах?
Приведу пример:
В моем случае создаем массив с 1024 размером для каждого игрока
new string[MAX_PLAYERS][1024];
И без проблем используем его во всем моде пример:
format(string[playerid], 33, "Hello, State, I'm %s", name(playerid));
SendClientMessageToAll(-1, string[playerid]);
и так далее по всему моду!
В случае моего знакомого мы должны создать в каждом паблике локальные массивы с разными размерами и использовать их, только там где мы их создали
Приведу пример:
public OnPlayerText(playerid, text[])
{
new string[33];
format(string, sizof(string), "Hello, State, I'm %s:%s", name(playerid),text));
SendClientMessageToAll(-1, string);
return false;
}
и т. д. мы создаем разные массивы с разными размерами в разных пабликах, а ведь мы знаем В PAWN изначальный размер стека (STK) - 16384 байт, не больше, не меньше
и в моде не один такой массив
если посчитать, у меня установлена 200 maxplayers, значит максимально 200*1024
и в случае моего друга, в моде примерно 30 пабликов которых мы используем, и создаем не 1 массив в каждом паблике примерно возьмем 10, ставим размер всегда по разному так что возьмем 256 ок 30*10*256*200(игроки которые вызывают эти функции)
Ну результат очевиден...
Я хотел бы узнать ваши мнение что вы считаете об этом, может быть я ошибаюсь где то? Какой бы вариант вы выбрали бы?
Maranzalla
16.03.2015, 02:38
В твоем случае будет
public OnPlayerText(playerid, text[])
{
format(string[playerid], 33, "Hello, State, I'm %s:%s", name(playerid),text);
SendClientMessageToAll(-1, string[playerid]);
return false;
}
вместо
public OnPlayerText(playerid, text[])
{
new string[33];
format(string, sizof(string), "Hello, State, I'm %s:%s", name(playerid),text);
SendClientMessageToAll(-1, string);
return false;
}
John_Smith (Scripter)
16.03.2015, 02:38
ну да, в любом паблике можно юзать,
public OnPlayerText(playerid, text[])
{
new string[33];
format(string, sizof(string), "Hello, State, I'm %s:%s", name(playerid),text));
SendClientMessageToAll(-1, string);
return false;
}
понял намек ша исправлю
Desulaid
16.03.2015, 16:18
К примеру я объявляю локальный стриг при использовании какой-либо локальной функции, а если глобальная - глобальную.
Например, в качестве локальной функции я приведу простой пример форматирования (format), а глобальная, то переменная MySQL, которая участвует во всех операциях, связанные с MySQL. Хотя и ее можно использовать локально.
Я могу и ошибаться, я жи не профессионал :D
NewGreen
16.03.2015, 16:37
Вообще лучше использовать локальные переменные!
Объясню почему, при одновременном использовании глобальных переменных в разных функциях, есть риск того что данные будут перезаписаны и может произойти ошибка, вплоть до того что сервер может отключится, и вы будете долго искать почему такое происходит.
Локальные переменные же, создаются каждый раз когда вызывается функция, а после того как функция выполнила свое действие, данные хранящиеся в переменной как и сама переменная уничтожаются, пример:
public func1(n) {
new x = 1; // Создали локальную переменную
printf("1 + %d = %d",n,x+n); // Функция выполнила действие
}
// Функция func1 уничтожила переменную x
public func2(n) {
printf("1 + %d = %d",n,x+n); // Ошибка, компилятор не знает о существовании x
}
Desulaid
16.03.2015, 18:09
Вообще лучше использовать локальные переменные!
Объясню почему, при одновременном использовании глобальных переменных в разных функциях, есть риск того что данные будут перезаписаны и может произойти ошибка, вплоть до того что сервер может отключится, и вы будете долго искать почему такое происходит.
Локальные переменные же, создаются каждый раз когда вызывается функция, а после того как функция выполнила свое действие, данные хранящиеся в переменной как и сама переменная уничтожаются, пример:
public func1(n) {
new x = 1; // Создали локальную переменную
printf("1 + %d = %d",n,x+n); // Функция выполнила действие
}
// Функция func1 уничтожила переменную x
public func2(n) {
printf("1 + %d = %d",n,x+n); // Ошибка, компилятор не знает о существовании x
}
Недолеко от истины ушел :)
Локально создавайте массивы, если статистика игрока: Убийства, смерти, уровень администратирования, то глобально.
John_Smith (Scripter)
16.03.2015, 19:27
Спасибо всем за ответы
Maranzalla
16.03.2015, 23:03
К примеру я объявляю локальный стриг при использовании какой-либо локальной функции, а если глобальная - глобальную.
Например, в качестве локальной функции я приведу простой пример форматирования (format), а глобальная, то переменная MySQL, которая участвует во всех операциях, связанные с MySQL. Хотя и ее можно использовать локально.
Я могу и ошибаться, я жи не профессионал :D
Самый весомый аргумент
Вообще лучше использовать локальные переменные!
Объясню почему, при одновременном использовании глобальных переменных в разных функциях, есть риск того что данные будут перезаписаны и может произойти ошибка, вплоть до того что сервер может отключится, и вы будете долго искать почему такое происходит.
Локальные переменные же, создаются каждый раз когда вызывается функция, а после того как функция выполнила свое действие, данные хранящиеся в переменной как и сама переменная уничтожаются, пример:
public func1(n) {
new x = 1; // Создали локальную переменную
printf("1 + %d = %d",n,x+n); // Функция выполнила действие
}
// Функция func1 уничтожила переменную x
public func2(n) {
printf("1 + %d = %d",n,x+n); // Ошибка, компилятор не знает о существовании x
}
Риск перезаписи данных? Хм, а разве в samp не "однозадачность"? Пока не закончит выполнение предыдущая функция/цикл и т.д - не будут выполняться следующие, соответственно, каким образом может возникнуть перезапись данных? Если использовать strcat, конечно, будет ужас, да и то это очень просто решается - strdel перед использованием. Или же я не прав и всё же лучше использовать "локальные массивы"?
Maranzalla
18.03.2015, 06:21
Риск перезаписи данных? Хм, а разве в samp не "однозадачность"? Пока не закончит выполнение предыдущая функция/цикл и т.д - не будут выполняться следующие, соответственно, каким образом может возникнуть перезапись данных? Если использовать strcat, конечно, будет ужас, да и то это очень просто решается - strdel перед использованием. Или же я не прав и всё же лучше использовать "локальные массивы"?
Прав но все равно локальные массивы
LINKINPARK
18.03.2015, 19:26
Один глобальный, просто не забывать его чистить масс[0] = EOS; однопоточность позволяет же. + глобальный массив не занимает стек.
Maranzalla
18.03.2015, 21:01
Один глобальный, просто не забывать его чистить масс[0] = EOS; однопоточность позволяет же. + глобальный массив не занимает стек.
Таскать по всему моду 1024 ячейки для одноразового использования ну это как минимум сумасшествие
John_Smith (Scripter)
18.03.2015, 22:04
ну я использую strdel каждый раз после использование массива для избежание смешивание информации, но все же что лучше использовать для оптимизации?
- - - Добавлено - - -
+ глобальный массив не занимает стек. Вот это то что нужно!
Чтобы избежать "смешивание" информации, то воспользуйтесь вариантом от 'LINKINPARK' и присвойте первой ячейке массива значение нулевого символа:
arr[0] = EOS;
из-за однопоточности данные не смешаются, НО я тестировал обычные переменные(int). Доступ к данным и вычисления у локальных переменных в этих тестах быстрее, чем у глобальных, по моим тестам быстрее всего выходит использовать локальные static переменные.
Чтобы избежать "смешивание" информации, то воспользуйтесь вариантом от 'LINKINPARK' и присвойте первой ячейке массива значение нулевого символа:
arr[0] = EOS;
А что если format используется в моде ну очень уж часто, тысячи раз, не проще ли будет использовать макрос и тд? Пример макроса с "обнулением" массива напишите кто-нибудь...
John_Smith (Scripter)
22.03.2015, 20:56
при использование format массив сам очищается, а после того как вы использовали strcat, советую вручную очищать массив после окончание функции со strcat
при использование format массив сам очищается, а после того как вы использовали strcat, советую вручную очищать массив после окончание функции со strcat
Со strcat всё предельно ясно, я в последнем посте на 1 странице уже написал по этому поводу. Я тоже думал что format очистит массив, но при одновременном использовании, для нескольких клиентов (игроков) - редко, но бывают путаницы, к примеру - цвет сообщения, 0 ID должен был получить зелёное сообщение, а 1 ID - жёлтое, в итоге всё получается наоборот. Пробовал очищать массив перед каждым использованием format - не компилируется мод вообще, просто зависает, почему и ищу другой способ какой-нибудь (кроме локальных массивов, хотелось бы всё же использовать глобальные).
John_Smith (Scripter)
25.03.2015, 03:23
Со strcat всё предельно ясно, я в последнем посте на 1 странице уже написал по этому поводу. Я тоже думал что format очистит массив, но при одновременном использовании, для нескольких клиентов (игроков) - редко, но бывают путаницы, к примеру - цвет сообщения, 0 ID должен был получить зелёное сообщение, а 1 ID - жёлтое, в итоге всё получается наоборот. Пробовал очищать массив перед каждым использованием format - не компилируется мод вообще, просто зависает, почему и ищу другой способ какой-нибудь (кроме локальных массивов, хотелось бы всё же использовать глобальные).
У меня в моде уже почти 4к строк, тобишь с нуля и везде использую глобальный массив игрока, мод работает как часы, все четка. И не думаю что в дальнейшем будут косяки:i-m_so_happy:
Powered by vBulletin® Version 4.2.0 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot