PDA

Просмотр полной версии : [Вопрос] стринги



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
}


Недолеко от истины ушел :)

L0ndl3m
16.03.2015, 19:26
Локально создавайте массивы, если статистика игрока: Убийства, смерти, уровень администратирования, то глобально.

John_Smith (Scripter)
16.03.2015, 19:27
Спасибо всем за ответы

Maranzalla
16.03.2015, 23:03
К примеру я объявляю локальный стриг при использовании какой-либо локальной функции, а если глобальная - глобальную.
Например, в качестве локальной функции я приведу простой пример форматирования (format), а глобальная, то переменная MySQL, которая участвует во всех операциях, связанные с MySQL. Хотя и ее можно использовать локально.
Я могу и ошибаться, я жи не профессионал :D

Самый весомый аргумент

Kazoox
17.03.2015, 21:20
Вообще лучше использовать локальные переменные!
Объясню почему, при одновременном использовании глобальных переменных в разных функциях, есть риск того что данные будут перезаписаны и может произойти ошибка, вплоть до того что сервер может отключится, и вы будете долго искать почему такое происходит.
Локальные переменные же, создаются каждый раз когда вызывается функция, а после того как функция выполнила свое действие, данные хранящиеся в переменной как и сама переменная уничтожаются, пример:



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 каждый раз после использование массива для избежание смешивание информации, но все же что лучше использовать для оптимизации?

- - - Добавлено - - -


+ глобальный массив не занимает стек. Вот это то что нужно!

L0ndl3m
18.03.2015, 23:03
Чтобы избежать "смешивание" информации, то воспользуйтесь вариантом от 'LINKINPARK' и присвойте первой ячейке массива значение нулевого символа:

arr[0] = EOS;

alfazlo
20.03.2015, 00:39
из-за однопоточности данные не смешаются, НО я тестировал обычные переменные(int). Доступ к данным и вычисления у локальных переменных в этих тестах быстрее, чем у глобальных, по моим тестам быстрее всего выходит использовать локальные static переменные.

Kazoox
22.03.2015, 20:31
Чтобы избежать "смешивание" информации, то воспользуйтесь вариантом от 'LINKINPARK' и присвойте первой ячейке массива значение нулевого символа:

arr[0] = EOS;

А что если format используется в моде ну очень уж часто, тысячи раз, не проще ли будет использовать макрос и тд? Пример макроса с "обнулением" массива напишите кто-нибудь...

John_Smith (Scripter)
22.03.2015, 20:56
при использование format массив сам очищается, а после того как вы использовали strcat, советую вручную очищать массив после окончание функции со strcat

Kazoox
23.03.2015, 10:28
при использование 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: