Оптимизации Pawn Кода

Описание: Основы скриптинга
Модератор: SJplayer

Дим M
Автор темы, Администратор
Администратор
Аватара
Дим M
Автор темы, Администратор
Администратор
Сообщения: 1608
Зарегистрирован: 5 апреля 2013
С нами: 10 лет 11 месяцев

#1 Дим » 20 апреля 2013, 20:25

Оптимизации Pawn Кода
Автор: eFFect aka YoYo.
Дополнил: zindo


Для начала, немного советов.

Совет #1:
Используйте в скрипте/моде как можно меньше таймеров. Каждый таймер способствует постепенному нарастанию грыжи у сервера.

Совет #2:
Функции которые не используются в таймерах, помещайте в stock а не в public

Совет #3:
При создании массивов типа:

Код: Выделить всё

new string[256];


Подумайте заранее, какая самая большая строка может использоваться в массиве, и максимально уменьшите число в квадратных скобках.
Макс. значение для SendClientMessage - 144.

Совет #4:
Соблюдайте табуляцию/выравнивание кода (лесенка) и не используйте функций типа tabsize.

Совет #5:
В некоторых случаях лучше использовать функцию напрямую, чем заводить для неё переменную.
Пример:

Код: Выделить всё

new var1; 
var1 
= GetPlayerSkin(playerid);
if(
var1 == 0) return SendClientMessage(playerid, 0xFF0000FF, "У вас скин CJ");


Лучше сделать так:

Код: Выделить всё

if(GetPlayerSkin(playerid) == 0) return SendClientMessage(playerid, 0xFF0000FF, "У вас скин CJ");


Совет #6:
Если в переменной может быть значение только 0 или 1, используйте тип переменной bool.
Пример:

Код: Выделить всё

PlayerInfo[playerid][pDriving];
/* Права на машину, они либо есть, либо их нет. 
Поэтому pDriving в enum'е лучше пометить типом bool:pDriving */
// С обычными переменными аналогично    


Совет #7:
Старайтесь меньше использовать такие константы как MAX_PLAYERS, MAX_VEHICLES и т.п.
Лучше сделать так:

Код: Выделить всё

#undef MAX_PLAYERS
#define MAX_PLAYERS 20    


где 20 - новое значение константы

Совет #8:
Старайтесь использовать стандартные функции, в большинстве случаев они быстрее чем их аналоги написанные сторонними скриптерами.
Яркий пример:

Код: Выделить всё

PlayerToPoint и IsPlayerRangeOfPoint


Совет #9:
В некоторых случаях лучше использовать switch нежели if/else
Пример:

Код: Выделить всё

if(var1 == 1) print("1");
else if(var1 == 2) print("2");
else if(var1 == 3) print("3");
else print("4"); 


Лучше записать так:

Код: Выделить всё

switch(var1)
{
    case 1: print("1");
    case 2: print("2");
    case 3: print("3");
    default: print("4");


Совет #10:
Если возможно, лучше использовать имя клавиши, нежели её код.
Пример: Клавиша Alt: KEY_WALK/1024 Лучше записать KEY_WALK.

Совет #11:
В большинстве случаев, использование паблика OnPlayerUpdate не оправдывает само себя, поэтому лучше с ним не злоупотреблять.

Совет #12:
Никогда не используйте цикл в цикле.
Пример:

Код: Выделить всё

for(new i = 0; i < MAX_PLAYERS; i++)
{
    for(new z = 0; z < MAX_PLAYERS; z++) // Этот цикл выполнится 500 по 500 (т.е. 500 раз по 500)
    {
    }


Совет #13:
Если вы часто используете один и тот же код, лучше создать для него функцию.

Пользуясь этими советами, вы добьётесь большей эффективности скриптинга. Как в быстродействии, так и в визуальном восприятии кода.

А теперь пара приёмов "оптимизированного" кода.

1. Структура switch:

Код: Выделить всё

switch(var1)
{
    case 0: var1 = 1;
    case 1: var1 = 1;
    case 2: var1 = 1;
    case 3: var1 = 2;
    case 4: var1 = 2;
    ...
}


Лучше записать так:

Код: Выделить всё

switch(var1)
{
    case 0..2: var1 = 1;
    case 3,4: var1 = 2;
}


2. Часто в функциях/командах используется:

Код: Выделить всё

SendClientMessage(playerid, 0xFFFFFFFF, "Текст");
return 1;


"Функцию" return, можно использовать в составе с любой функцией которая возвращает 1 или 0 (истина или ложь).
В нашем примере можно сделать так:

Код: Выделить всё

return SendClientMessage(playerid, 0xFFFFFFFF, "Текст");


2.1. Если функция возвращает true/else по условию:

Код: Выделить всё

if(!strcmp("text", "text", true)) return 1;
else return 0;


Можно записать так:

Код: Выделить всё

!strcmp("text", "text", true)?true:false;


3. Использование псевдодинамических массивов для оптимизации циклов типа:

Код: Выделить всё

for(new i; i<MAX_PLAYERS; i++) { ... }


4. Использование массива вместо функции GetPlayerName (либо ее аналога, GetPlayerNameEx) для узнавания никнейма игрока.

Код: Выделить всё

new PlayerName[MAX_PLAYERS][MAX_PLAYER_NAME];


Далее в OnPlayerConnect'e записываем никнейм игрока в массив:

Код: Выделить всё

GetPlayerName(playerid, PlayerName[playerid], MAX_PLAYER_NAME);


При каждом изменении ника по сценарию мода также добавляем эту строку (например в команду /setname)
При выходе игрока нужно очистить его ячейку в массиве:

Код: Выделить всё

PlayerName[playerid][0] = 0;


Пример использование:

Код: Выделить всё

format(str, 128, "Ник игрока под идом 5 '%s'", PlayerName[5]);



Для этого создаем глобальный двумерный массив:
[center]i love you [s]mxIni[/s] Mysql[/center]


Вернуться в «Основы скриптинга»

Кто сейчас на форуме (по активности за 5 минут)

Сейчас этот раздел просматривают: 9 гостей