Доступ к архиву

Переход в группу "Пользователь"

300.00 ₽
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

Оптимизация.

Статус
В этой теме нельзя размещать новые ответы.

Barni

Компетентный
Давно я не делал для форума не чего полезного из - за своей лени :D Вот думаю сейчас принесу хоть маленькую пользу:)

Начнём с самого простого.

Это имя игрока.
Чаще всего юзеры создают стоки типо stock GetName(playerid) stock PlayerName(playerid) и т.п.
Или же стандартной функцией GetPlayerName(playerid,PlayerName,24);
Лучше всего заменить эти два способа этим:
Создадим переменную для записи ника игрока.
PHP:
new PlayerName[MAX_PLAYERS][MAX_PLAYER_NAME];
При входе игрока на сервер запишем его ник в переменную которую создали выше.
PHP:
public OnPlayerConnect(playerid)
{
     GetPlayerName(playerid,PlayerName[playerid],MAX_PLAYER_NAME);
}
Пример использования:
PHP:
if (strcmp("/getmyname", cmdtext, true, 10) == 0)
{
		new string[50];
		format(string,sizeof(string),"Ваш ник: %s",PlayerName[playerid]);
		SendClientMessage(playerid,-1,string);
		return 1;
}
По мне дак гораздо компактнее)

switch
Если вам нужно перебрать более 3-4 значений, то лучше использовать switch нежели if/else if. Switch работает быстрее, да и код выглядит куда аккуратней.
Пример с использованием switch:
PHP:
new figures;
switch(figures)
{
    case 0: 
    {
    //Действие
    }
    case 1: 
    {
    //Действие
    }
    case 2: 
    {
    //Действие
    }
    case 3: 
    {
    //Действие
    }
    case 4: 
    {
    //Действие
    }
    case 5: 
    {
    //Действие
    }
    default:
    {
       SendClientMessage(playerid,-1,"Нет такого значения");
    }
}
default - Здесь будут ваши действия если в переменной нет значений, которое указаны в case.
Если у нескольких ваших значений есть одинаковые действия:
PHP:
new figures;
switch(figures)
{
    case 0...10:// Значения от 0 до 10 включительно
    {
    //Действия
    }
    default:
    {
       //Действия, если в переменной нету значений от 0 до 10
    }
}
Второй способ:
PHP:
new figures;
switch(figures)
{
   case 0,5,12,15:
   {
     //действия для значений 0,5,12,15
   }
   case 1,3,6,9:
   {
    //Действия для значений 1,3,6,9
   }
   default:
    {
       //Действия, если в переменной нет значений которые указаны в case, то есть 0,5,12,15,1,3,6,9
    }
}
Switch лучше всего использовать в public OnPlayerDialog
Stock и public
Если public не вызывается таймером, то лучше заменить его на stock, так как для stock'a не надо выделать forward соответственно он кушает меньше памяти.
Sting
В своей прошлой теме я уже писал, что бессмысленно использовать огромные стринги типа new string[1000]; new string[512]; new string[1024];
Исключение запросы к базам данных(MySQL).
Ну сразу приведу пример, что бы не было вопросов.
PHP:
new string[128];
new Name[MAX_PLAYER_NAME];
GetPlayerName(playerid,Name,MAX_PLAYER_NAME);
format(playerid,string,sizeof(string),"Ваш ник: %",Name);
SendClientMessage(playerid,-1,string);
В этом примере ясно видно, что в переменной string используется более 50 лишних ячеек. Почему лишних? Потому что мы используем всего 9символов + 24+1, так как переменная Name имеет размер 24 ячейки. Итого мы получаем 128-34= 94 лишних ячейки, пробел тоже считается за символ т.е. 1 ячейку.Откуда взялась ещё одна ячейка? Это экстра ячейка, она служит для идентификатора строки. Тоесть цифра в квадратных скобках всегда больше значения переменной на единицу.

Полезно* отличная замена
PHP:
format(string,sizeof(string)"......",....);
SendClientMessage(playerid,-1,string);

Или 

format(string,sizeof(string)"......",....);
SendClientMessageToAll(-1,string);
Функция позваляет использовать SendClientMessage без string, что повышает быстродействие:
В начало мода:
PHP:
#define BYTES_PER_CELL (cellbits / 8)
PHP:
stock SendMes(playerid, fstring[], {Float, _}:...)
{
    static const STATIC_ARGS = 3;
    new n = (numargs() - STATIC_ARGS) * BYTES_PER_CELL;
    if (n)
    {
        new message[128], arg_start, arg_end;
        #emit CONST.alt        fstring
        #emit LCTRL          5
        #emit ADD
        #emit STOR.S.pri        arg_start
        #emit LOAD.S.alt        n
        #emit ADD
        #emit STOR.S.pri        arg_end
        do
        {
            #emit LOAD.I
            #emit PUSH.pri
            arg_end -= BYTES_PER_CELL;
            #emit LOAD.S.pri      arg_end
        }
        while (arg_end > arg_start);
        // Push the static format parameters.
        #emit PUSH.S          fstring
        #emit PUSH.C          128
        #emit PUSH.ADR         message
        n += BYTES_PER_CELL * 3;
        #emit PUSH.S          n
        #emit SYSREQ.C         format
        n += BYTES_PER_CELL;
        #emit LCTRL          4
        #emit LOAD.S.alt        n
        #emit ADD
        #emit SCTRL          4
        return SendClientMessage(playerid, -1, message);
    }
    else return SendClientMessage(playerid, -1, fstring);
}  
stock SendMesAll(fstring[], {Float, _}:...) 
{ 
    static const STATIC_ARGS = 2; 
    new n = (numargs() - STATIC_ARGS) * BYTES_PER_CELL; 
    if (n) 
    { 
        new message[128], arg_start, arg_end; 
        #emit CONST.alt        fstring 
        #emit LCTRL          5 
        #emit ADD 
        #emit STOR.S.pri        arg_start 
        #emit LOAD.S.alt        n 
        #emit ADD 
        #emit STOR.S.pri        arg_end 
        do 
        { 
            #emit LOAD.I 
            #emit PUSH.pri 
            arg_end -= BYTES_PER_CELL; 
            #emit LOAD.S.pri      arg_end 
        } 
        while (arg_end > arg_start); 
        // Push the static format parameters. 
        #emit PUSH.S          fstring 
        #emit PUSH.C          128 
        #emit PUSH.ADR         message 
        n += BYTES_PER_CELL * 3; 
        #emit PUSH.S          n 
        #emit SYSREQ.C         format 
        n += BYTES_PER_CELL; 
        #emit LCTRL          4 
        #emit LOAD.S.alt        n 
        #emit ADD 
        #emit SCTRL          4 
        return SendClientMessageToAll(-1, message); 
    } 
    else return SendClientMessageToAll(-1, fstring); 
}
Пример использования:
PHP:
new Name[MAX_PLAYER_NAME];
GetPlayerName(playerid,Name,MAX_PLAYER_NAME);
SendMes(playerid, "{FF0000}Ваш ник: {000000} %s",,Name);
SendMesAll("{FF0000}Ник %s ",Name);
Авторы: Zeex и Y_Less
Едем дальше..
Циклы MAX_PLAYERS
Сама оптимальная оптимизация этих циклов это инклюд foreach, автор которого Y_Less Ссылка:
Саздаём блокнот, называем его foreach.inc, закидываем его в папку pawno/include и подключаем его к моду.
PHP:
#include <foreach>
Далее качаем библиотеку YSI, в дальнейшем она нам понадобится Ссылка:
Тут тоже самое открываем в архиве папку pawno/include и копируем содержимое в вашу папку павно pawno/include

Теперь приступим к оптимизации циклов MAX_PLAYERS или GetMaxPlayers(); у кого как:)

Находим любой цикл MAX_PLAYERS или GetMaxPlayers(); я буду показывать пример Y_Less'a
Обычный цикл:
PHP:
for (new i = 0; i != MAX_PLAYERS; ++i)
{
    if (IsPlayerConnected(i))
    {
        printf("Игрок под идом %d присоединился", i);
    }
}
Теперь тоже самое, но с foreach
PHP:
foreach (new i : Player)
{
    printf("Игрок под идом %d присоединился", i);
}
Разница этих циклов в том, что foreach перебирает, только подключённых игроков, а не как MAX_PLAYERS - 800, GetMaxPlayers(); - Столько сколько указано слотов в конфиге сервера.
Тесты Ziggi:

PHP:
IsPlayerConnected: 888
GetMaxPlayers: 304
GetPlayerLastID: 2169 (модифицированный Ziggi способ от Alex009)
PLID: 145 (от OFFREAL)
foreach: 123 (foreach от Y_Less’a)
foreach_step: 134 (foreach который опубликовал степашка)
forscan: 168 (forscan от Jester(более удобный PLID))
Тут конечно же видно что foreach работает быстрее всех.
Пока всё, по возможности буду дополнять
 
Последнее редактирование:
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу