Активный
- Тема Автор
- #1
Оптимизация улучшает производительность сервера. Разберем основные техники.
Оптимизация циклов
Оптимизация строк
Оптимизация проверок
Оптимизация таймеров
Оптимизация массивов
Оптимизация функций
Оптимизация OnPlayerUpdate
Оптимизация диалогов
Оптимизация TextDraw
Оптимизация проверок расстояния
Важные моменты:
- Профилируйте код для поиска узких мест
- Избегайте преждевременной оптимизации
- Измеряйте производительность до и после
- Документируйте оптимизации
Оптимизация улучшает работу сервера!
Оптимизация циклов
Код:
// ПЛОХО - проверка на каждой итерации
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i))
{
// код
}
}
// ХОРОШО - кеширование размера
new maxPlayers = GetMaxPlayers();
for(new i = 0; i < maxPlayers; i++)
{
if(IsPlayerConnected(i))
{
// код
}
}
// ЕЩЕ ЛУЧШЕ - использование foreach
foreach(new i : Player)
{
// код
}
Оптимизация строк
Код:
// ПЛОХО - создание новой строки каждый раз
for(new i = 0; i < 100; i++)
{
new string[128];
format(string, sizeof(string), "Игрок %d", i);
}
// ХОРОШО - переиспользование строки
new string[128];
for(new i = 0; i < 100; i++)
{
format(string, sizeof(string), "Игрок %d", i);
// использование строки
}
Оптимизация проверок
Код:
// ПЛОХО - множественные проверки
if(IsPlayerConnected(playerid))
{
if(GetPlayerMoney(playerid) > 0)
{
if(GetPlayerHealth(playerid) > 0)
{
// код
}
}
}
// ХОРОШО - ранний выход
if(!IsPlayerConnected(playerid)) return 0;
if(GetPlayerMoney(playerid) <= 0) return 0;
if(GetPlayerHealth(playerid) <= 0) return 0;
// код
Оптимизация таймеров
Код:
// ПЛОХО - слишком частые таймеры
SetTimer("UpdatePlayer", 100, true);
// ХОРОШО - оптимальная частота
SetTimer("UpdatePlayer", 1000, true);
// Использование одного таймера для нескольких задач
forward MainTimer();
public MainTimer()
{
UpdatePlayers();
UpdateVehicles();
UpdateBusinesses();
}
Оптимизация массивов
Код:
// Используйте правильные размеры массивов
new PlayerData[MAX_PLAYERS][PlayerInfo]; // правильно
new PlayerData[1000][PlayerInfo]; // избыточно
// Используйте индексацию вместо поиска
new playerIndex[MAX_PLAYERS] = {-1, ...};
// Быстрый доступ по индексу вместо поиска
Оптимизация функций
Код:
// Используйте stock для неиспользуемых функций
stock UnusedFunction()
{
// код
}
// Используйте inline для простых функций
#define GetDistance(%1,%2,%3,%4,%5,%6) \
floatsqroot((%1-%4)*(%1-%4) + (%2-%5)*(%2-%5) + (%3-%6)*(%3-%6))
Оптимизация OnPlayerUpdate
Код:
// ПЛОХО - тяжелые операции в OnPlayerUpdate
public OnPlayerUpdate(playerid)
{
SavePlayerData(playerid); // слишком часто
return 1;
}
// ХОРОШО - использование таймеров
new lastUpdate[MAX_PLAYERS];
public OnPlayerUpdate(playerid)
{
if(GetTickCount() - lastUpdate[playerid] > 5000)
{
// легкие операции
lastUpdate[playerid] = GetTickCount();
}
return 1;
}
// Тяжелые операции в отдельном таймере
SetTimerEx("SavePlayerData", 60000, true, "i", playerid);
Оптимизация диалогов
Код:
// Кешируйте списки диалогов
new weaponList[512];
ShowWeaponDialog(playerid)
{
if(strlen(weaponList) == 0)
{
// Генерация списка один раз
for(new i = 0; i < sizeof(WeaponList); i++)
{
format(weaponList, sizeof(weaponList), "%s%s\n", weaponList, WeaponList[i][wName]);
}
}
ShowPlayerDialog(playerid, DIALOG_WEAPONS, DIALOG_STYLE_LIST, "Оружие", weaponList, "Выбрать", "Отмена");
}
Оптимизация TextDraw
Код:
// Обновляйте только при изменении
new lastMoney[MAX_PLAYERS];
UpdateMoneyTextDraw(playerid)
{
new money = GetPlayerMoney(playerid);
if(money != lastMoney[playerid])
{
new string[32];
format(string, sizeof(string), "$%d", money);
TextDrawSetString(moneyTextDraw, string);
lastMoney[playerid] = money;
}
}
Оптимизация проверок расстояния
Код:
// Используйте квадрат расстояния для сравнения
stock IsPlayerInRange(playerid, Float:x, Float:y, Float:z, Float:range)
{
new Float:px, Float:py, Float:pz;
GetPlayerPos(playerid, px, py, pz);
new Float:distance = floatsqroot(
floatpower(px - x, 2) +
floatpower(py - y, 2) +
floatpower(pz - z, 2)
);
return distance <= range;
}
// Оптимизированная версия без квадратного корня
stock IsPlayerInRangeFast(playerid, Float:x, Float:y, Float:z, Float:range)
{
new Float:px, Float:py, Float:pz;
GetPlayerPos(playerid, px, py, pz);
new Float:distanceSq =
floatpower(px - x, 2) +
floatpower(py - y, 2) +
floatpower(pz - z, 2);
return distanceSq <= floatpower(range, 2);
}
Важные моменты:
- Профилируйте код для поиска узких мест
- Избегайте преждевременной оптимизации
- Измеряйте производительность до и после
- Документируйте оптимизации
Оптимизация улучшает работу сервера!