Оптимизация | Индивидуальные таймеры
Добрый день, пользователи Pro-Pawn.
В этом уроке я хочу донести до вас довольно значимый способ оптимизации мода, который известен далеко не всем. Но сразу предупреждаю, если вы очень слабый скриптер, не читайте дальше и не пишите ничего в этой теме.
Итак, таймеры. Многие считают что использовать кучу таймеров в моде - ужасно плохо, но это не так, если использовать их разумно. Нагружают сервер действия, срабатываемые в таймере, а не сами таймеры (совсем немного). Поэтому 1000 разумно сделанных таймеров будут полезнее чем 5 кое-как сделанных. Если вы это понимаете - идём дальше, иначе закрывайте тему.
Почти в каждом моде есть таймер, допустим на 1 секунду. В этом таймере есть цикл на всех игроков сервера, где с ними производятся действия. Например:
PHP код:
public Timer1Second()
{
foreach(...)
{
// Действия
}
return 1;
}
Именно из за таких таймеров серверы с большим онлайном начинают испытывать лаги и ищут более мощный хостинг. Всё дело в том, что одно срабатывание из foreach (для одного игрока) проходит например за 0.25 - 1 мс (в зависимости от оптимизации и мощности процессора), что впрочем то не так уж и страшно. Но когда игроков 200, выполнение таймера занимает уже от 50 мс до 200 мс каждую секунду и пока весь таймер не закончит своё действие, сервер своими делами не займётся (синхронизация игроков и т.п.), поэтому в эти 200 мс сервер тупо висит - вот она причина лагов. Теперь давайте разберём как избавиться от этого и не мешать серверу заниматься необходимыми для работы сервера делами.
1) Убрать из ВСЕХ таймеров такие циклы с игроками.
2) Объявить глобальный массив (ко всем new):
PHP код:
new PlayerTimerID[MAX_PLAYERS];
3) Ко всем forward:
PHP код:
forward PlayerUpdate(playerid);
4) В OnPlayerConnect:
PHP код:
PlayerTimerID[playerid] = SetTimerEx("PlayerUpdate", 250, 1, "d", playerid);
5) В OnPlayerDisconnect:
PHP код:
KillTimer(PlayerTimerID[playerid]);
6) В конце мода:
PHP код:
public PlayerUpdate(playerid)
{
return 1;
}
В итоге мы получим индивидуальный таймер для каждого игрока, да, их будет 1000 при максимальном онлайне, но ничего страшного - серверу только лучше. Теперь все действия с игроком нужно использовать в PlayerUpdate (он срабатывает каждые 250 мс). Отдельные таймеры на 1 сек и т.п. создавать не нужно, просто подсчитывайте количество срабатываний PlayerUpdate (1 сек = 4 срабатывания) и выполняйте нужные действия.
И что же нам это всё даст? Когда сервер выполнял цикл, он выполнял его полностью на всех игроков и пока не закончил - другими делами не занимался. В нашем случае для каждого игрока идут отдельные таймеры, срабатывающие в разное время, а не сразу все. Поэтому между срабатываниями таймеров, пусть оно будет даже 0,01 мс, но сервер в это время займётся своими делами и ему хватит этого времени, а значит сервер не будет останавливаться в ожидании.
На этом всё, надеюсь что объяснил достаточно понятно. Удачного скриптинга!