Просмотр полной версии : [Вопрос] Мысли по оптимизации кода
Доброго времени суток.
Написал систему одну, ну и вижу, что код получился, мягко говоря "не очень"
Может будут у кого-то мысли по его оптимизации?
Запрос в БД
mysql_function_query(MysqlConnect, "SELECT `p_leader`,`online_status`,`nickname` FROM `"TABLE_ACC"`", true, "OnCheckLEADCallBack","");
forward OnCheckLEADCallBack();
public OnCheckLEADCallBack()
{
new rows, fields;
cache_get_data(rows, fields,MysqlConnect);
cache_get_row_count(rows);
if(rows == 0) return 1;
new count[2];
new online_pl = -1;
new names_one[MAX_PLAYER_NAME+1];
new names_two[MAX_PLAYER_NAME+1];
new pl_leader;
for(new i = 0; i < rows; i++)
{
pl_leader = cache_get_field_content_int(i,"p_leader",MysqlConnect);
if(pl_leader == 0) continue;
if(count[0] != 0 && count[1] != 0) break;
if(pl_leader == 6)
{
online_pl = cache_get_field_content_int(i,"online_status",MysqlConnect);
if(online_pl == -1) cache_get_field_content(i,"nickname",names_one,MysqlConnect,MAX_PLAYER_NAME);
else GetPlayerName(online_pl,names_one,MAX_PLAYER_NAME);
count[0] ++;
continue;
}
else if(pl_leader != 6)
{
if(count[0] == 0)
{
strmid(names_one, "Нет", 0, strlen("Нет"), 4);
continue;
}
}
if(pl_leader == 8)
{
online_pl = cache_get_field_content_int(i,"online_status",MysqlConnect);
if(online_pl == -1) cache_get_field_content(i,"nickname",names_two,MysqlConnect,MAX_PLAYER_NAME);
else GetPlayerName(online_pl,names_two,MAX_PLAYER_NAME);
count[1] ++;
continue;
}
else if(pl_leader != 8)
{
if(count[1] == 0)
{
strmid(names_two, "Нет", 0, strlen("Нет"), 4);
continue;
}
}
}
printf("На выходе получаем: Names1: %s | Names2: %s",names_one,names_two);
return 1;
}
Что первое в голову пришло
forward OnCheckLEADCallBack();
public OnCheckLEADCallBack()
{
new
rows, fields,
online_pl = -1,
name[2][MAX_PLAYER_NAME+1],
pl_leader;
cache_get_data(rows, fields,MysqlConnect);
cache_get_row_count(rows);
if(rows == 0)
return 1;
for(new i = 0, j = 0; i < rows; i++)
{
pl_leader = cache_get_field_content_int(i,"p_leader",MysqlConnect);
if(pl_leader == 0)
continue;
if(pl_leader == 6 || pl_leader == 8)
{
online_pl = cache_get_field_content_int(i, "online_status", MysqlConnect);
if (online_pl == -1)
cache_get_field_content(i,"nickname", name[j], MysqlConnect, MAX_PLAYER_NAME);
else
GetPlayerName(online_pl, name[j], MAX_PLAYER_NAME);
if (strlen(name[j]) == 0)
strcat(name[j], "Нет");
j++;
}
}
printf("На выходе получаем: Names1: %s | Names2: %s", name[0], name[1]);
return 1;
}
Что первое в голову пришло
forward OnCheckLEADCallBack();
public OnCheckLEADCallBack()
{
new
rows, fields,
online_pl = -1,
name[2][MAX_PLAYER_NAME+1],
pl_leader;
cache_get_data(rows, fields,MysqlConnect);
cache_get_row_count(rows);
if(rows == 0)
return 1;
for(new i = 0, j = 0; i < rows; i++)
{
pl_leader = cache_get_field_content_int(i,"p_leader",MysqlConnect);
if(pl_leader == 0)
continue;
if(pl_leader == 6 || pl_leader == 8)
{
online_pl = cache_get_field_content_int(i, "online_status", MysqlConnect);
if (online_pl == -1)
cache_get_field_content(i,"nickname", name[j], MysqlConnect, MAX_PLAYER_NAME);
else
GetPlayerName(online_pl, name[j], MAX_PLAYER_NAME);
if (strlen(name[j]) == 0)
strcat(name[j], "Нет");
j++;
}
}
printf("На выходе получаем: Names1: %s | Names2: %s", name[0], name[1]);
return 1;
}
Суть вот в чём:
Если вообще не найдено игроков с лидерством 6 или 8, значит записываем в name = Нет
В твоём случае, моя цель достигнута не будет)
Спасибо большое за Вашу мысль оптимизации)
Опиши структуру таблицы (названия столбцов + какие данные хранятся и в каких количествах), а так же то, какой результат ты хочешь получить.
Если ты просто ищешь двух игроков по определённому условию, то гораздо оптимизированнее будет сделать выборку в запросе, а не выгружать все данные и делать выборку на стороне сервера.
Опиши структуру таблицы (названия столбцов + какие данные хранятся и в каких количествах), а так же то, какой результат ты хочешь получить.
Если ты просто ищешь двух игроков по определённому условию, то гораздо оптимизированнее будет сделать выборку в запросе, а не выгружать все данные и делать выборку на стороне сервера.
Я хотел получить двух игроков, просто далее, я намерен использовать диалог, где буду использовать их ники, если же, игроков с данными лидерками найдено не будет, вместо ника в диалоговом окне будет показано "Нет"
Названия столбцов сами за себя говорят.
"SELECT `p_leader`,`online_status`,`nickname` FROM `"TABLE_ACC"` WHERE `p_leader` != '0'"
forward OnCheckLEADCallBack();
public OnCheckLEADCallBack()
{
new
rows,
fields,
online_pl,
pl_leader,
name[MAX_PLAYER_NAME+1],
string[MAX_PLAYER_NAME*10];
cache_get_data(rows, fields, MysqlConnect);
if(rows == 0)
return 1;
for(new i = 0; i < rows; i++)
{
pl_leader = cache_get_field_content_int(i, "p_leader", MysqlConnect);
online_pl = cache_get_field_content_int(i, "online_status", MysqlConnect);
if (online_pl == -1)
cache_get_field_content(i, "nickname", name, MysqlConnect, MAX_PLAYER_NAME);
else
GetPlayerName(online_pl, name, MAX_PLAYER_NAME);
if (i != 0)
strcat(string, "\n");
strcat(string, name);
}
printf("%s", string);
return 1;
}
"SELECT `p_leader`,`online_status`,`nickname` FROM `"TABLE_ACC"` WHERE `p_leader`!= '0'"
forward OnCheckLEADCallBack();
public OnCheckLEADCallBack()
{
new
rows,
fields,
online_pl,
pl_leader,
name[MAX_PLAYER_NAME+1],
string[MAX_PLAYER_NAME*10];
cache_get_data(rows, fields, MysqlConnect);
if(rows == 0)
return 1;
for(new i = 0; i < rows; i++)
{
pl_leader = cache_get_field_content_int(i, "p_leader", MysqlConnect);
online_pl = cache_get_field_content_int(i, "online_status", MysqlConnect);
if (online_pl == -1)
cache_get_field_content(i, "nickname", name, MysqlConnect, MAX_PLAYER_NAME);
else
GetPlayerName(online_pl, name, MAX_PLAYER_NAME);
if (i != 0)
strcat(string, "\n");
if (strlen(name) != 0)
strcat(string, name);
else
strcat(string, "Нет");
}
printf("%s", string);
return 1;
}
"SELECT `p_leader`,`online_status`,`nickname` FROM `"TABLE_ACC"` WHERE `p_leader`!= '0'"
forward OnCheckLEADCallBack();
public OnCheckLEADCallBack()
{
new
rows,
fields,
online_pl,
pl_leader,
name[MAX_PLAYER_NAME+1],
string[MAX_PLAYER_NAME*10];
cache_get_data(rows, fields, MysqlConnect);
if(rows == 0)
return 1;
for(new i = 0; i < rows; i++)
{
pl_leader = cache_get_field_content_int(i, "p_leader", MysqlConnect);
online_pl = cache_get_field_content_int(i, "online_status", MysqlConnect);
if (online_pl == -1)
cache_get_field_content(i, "nickname", name, MysqlConnect, MAX_PLAYER_NAME);
else
GetPlayerName(online_pl, name, MAX_PLAYER_NAME);
if (i != 0)
strcat(string, "\n");
if (strlen(name) != 0)
strcat(string, name);
else
strcat(string, "Нет");
}
printf("%s", string);
return 1;
}
Так а если нужны конкретно лидеры 6 и 7 фракции?
Так а если нужны конкретно лидеры 6 и 7 фракции?
forward OnCheckLEADCallBack();
public OnCheckLEADCallBack()
{
new
rows,
fields,
online_pl,
pl_leader,
name[MAX_PLAYER_NAME+1],
string[MAX_PLAYER_NAME*10];
cache_get_data(rows, fields, MysqlConnect);
if(rows == 0)
return 1;
for(new i = 0; i < rows; i++)
{
pl_leader = cache_get_field_content_int(i, "p_leader", MysqlConnect);
if (pl_leader == 6 || pl_leader == 7)
{
online_pl = cache_get_field_content_int(i, "online_status", MysqlConnect);
if (online_pl == -1)
cache_get_field_content(i, "nickname", name, MysqlConnect, MAX_PLAYER_NAME);
else
GetPlayerName(online_pl, name, MAX_PLAYER_NAME);
if (i != 0)
strcat(string, "\n");
if (strlen(name) != 0)
strcat(string, name);
else
strcat(string, "Нет");
}
}
printf("%s", string);
return 1;
}
forward OnCheckLEADCallBack();
public OnCheckLEADCallBack()
{
new
rows,
fields,
online_pl,
pl_leader,
name[MAX_PLAYER_NAME+1],
string[MAX_PLAYER_NAME*10];
cache_get_data(rows, fields, MysqlConnect);
if(rows == 0)
return 1;
for(new i = 0; i < rows; i++)
{
pl_leader = cache_get_field_content_int(i, "p_leader", MysqlConnect);
if (pl_leader == 6 || pl_leader == 7)
{
online_pl = cache_get_field_content_int(i, "online_status", MysqlConnect);
if (online_pl == -1)
cache_get_field_content(i, "nickname", name, MysqlConnect, MAX_PLAYER_NAME);
else
GetPlayerName(online_pl, name, MAX_PLAYER_NAME);
if (i != 0)
strcat(string, "\n");
if (strlen(name) != 0)
strcat(string, name);
else
strcat(string, "Нет");
}
}
printf("%s", string);
return 1;
}
Снова не до поняли, вот в моём примере я сделал вот как:
Ищу лидеров фракций.
Далее отсеиваю игроков, у которых ячейка p_leader равна 0
Далее, если нашло лидера Фракции 6 - Я получаю его имя, ровно так-же и с 7 фракцией.
НО, если игроков с такой лидеркой не нашло, я присваиваю переменной "Нет"
"SELECT `nickname`,`p_leader`,`online_status` FROM `"TABLE_ACC"` WHERE `p_leader` in (6,7)"
В адресуемом "pulic xxxx" будут только с 6,7 или то что укажете в запросе:
Пример
in (6,7,8,10,200,555,5555)
Снова не до поняли, вот в моём примере я сделал вот как:
Ищу лидеров фракций.
Далее отсеиваю игроков, у которых ячейка p_leader равна 0
Далее, если нашло лидера Фракции 6 - Я получаю его имя, ровно так-же и с 7 фракцией.
НО, если игроков с такой лидеркой не нашло, я присваиваю переменной "Нет"
А тогда зачем проверка, находится игрок на сервере или нет?
Взяв твой код. Откуда online_pl берет ид игрока для GetPlayerName?
При авторизации, регистрации записывается ид игрока туда
При авторизации, регистрации записывается ид игрока туда
Как оно записывается в переменную, если она не глобальная? Тогда может лучше так?
mysql_function_query(MysqlConnect, "SELECT `p_leader`,`online_status`,`nickname` FROM `"TABLE_ACC"`", true, "OnCheckLEADCallBack","i", playerid);
forward OnCheckLEADCallBack(playerid);
public OnCheckLEADCallBack(playerid)
Как оно записывается в переменную, если она не глобальная? Тогда может лучше так?
mysql_function_query(MysqlConnect, "SELECT `p_leader`,`online_status`,`nickname` FROM `"TABLE_ACC"`", true, "OnCheckLEADCallBack","i", playerid);
forward OnCheckLEADCallBack(playerid);
public OnCheckLEADCallBack(playerid)
Так оно так-бы и было))
Так а что делать с этим то?
Ищу лидеров фракций.
Далее отсеиваю игроков, у которых ячейка p_leader равна 0
Далее, если нашло лидера Фракции 6 - Я получаю его имя, ровно так-же и с 7 фракцией.
НО, если игроков с такой лидеркой не нашло, я присваиваю переменной "Нет"
Вот, что снова, так сказать получилось по моей задумке:
forward OnCheckLEADCallBack();
public OnCheckLEADCallBack()
{
new
rows,
fields,
pl_leader,
name[MAX_PLAYER_NAME+1],names[MAX_PLAYER_NAME+1];
cache_get_data(rows, fields, MysqlConnect);
if(rows == 0) return 1;
new count[2];
for(new i = 0; i < rows; i++)
{
pl_leader = cache_get_field_content_int(i, "p_leader", MysqlConnect);
if(pl_leader == 6)
{
if(count[0] == 0)
{
cache_get_field_content(i, "nickname", name, MysqlConnect, MAX_PLAYER_NAME);
count[0] ++;
}
}
if(pl_leader == 7)
{
if(count[1] == 0)
{
cache_get_field_content(i, "nickname", names, MysqlConnect, MAX_PLAYER_NAME);
count[1]++;
}
}
}
if(count[0] == 0) strmid(name, "Нет", 0, strlen("Нет"), 4);
if(count[1] == 0) strmid(names, "Нет", 0, strlen("Нет"), 4);
printf("На выходе получаем: Фракция 1: %s | Фракция 2: %s",name,names);
return 1;
}
На выходе имеем:
На выходе получаем: Фракция 1: Нет | Фракция 2: Test_Account
Или же при отсутствия игроков с данными лидерками:
На выходе получаем: Фракция 1: Нет | Фракция 2: Нет
Вот и я хотел добиться такого-же эффекта, только с меньшими затратами, вот прямо чую, что можно сделать в 50 раз лучше, но, не пойму как...
А получение онлайн статуса теперь в принципе не нужно. Так-как изменил задумку данной фичи)
Тебе двое людей выше уже сказали, что выборку лучше делать на стороне субд, чем циклом вручную.
mysql_function_query(MysqlConnect, !"SELECT `nickname`,`p_leader` FROM `"TABLE_ACC"` WHERE `p_leader` in (6,7)",
true, !"OnCheckLEADCallBack", "");
forward OnCheckLEADCallBack();
public OnCheckLEADCallBack()
{
new rows,
fields,
name1[MAX_PLAYER_NAME+1] = "Нет",
name2[MAX_PLAYER_NAME+1] = "Нет";
cache_get_data(rows, fields, MysqlConnect);
if(rows == 0) goto SKIP_CYCLE;
for(new i; i < rows; i++)
{
if(cache_get_field_content_int(i, "p_leader", MysqlConnect) == 6)
{
name1[0] = EOS;//не помню, чистит ли cache_get_field_content строку, если да - удалить это поле
cache_get_field_content(i, "nickname", name1, MysqlConnect, MAX_PLAYER_NAME);
}
else
{
name2[0] = EOS;
cache_get_field_content(i, "nickname", name2, MysqlConnect, MAX_PLAYER_NAME);
}
}
SKIP_CYCLE:
printf("На выходе получаем: Фракция 6: %s | Фракция 7: %s", name1, name2);
return 1;
}
Тебе двое людей выше уже сказали, что выборку лучше делать на стороне субд, чем циклом вручную.
mysql_function_query(MysqlConnect, !"SELECT `nickname`,`p_leader` FROM `"TABLE_ACC"` WHERE `p_leader` in (6,7)",
true, !"OnCheckLEADCallBack", "");
forward OnCheckLEADCallBack();
public OnCheckLEADCallBack()
{
new rows,
fields,
name1[MAX_PLAYER_NAME+1] = "Нет",
name2[MAX_PLAYER_NAME+1] = "Нет";
cache_get_data(rows, fields, MysqlConnect);
if(rows == 0) goto SKIP_CYCLE;
for(new i; i < rows; i++)
{
if(cache_get_field_content_int(i, "p_leader", MysqlConnect) == 6)
{
name1[0] = EOS;//не помню, чистит ли cache_get_field_content строку, если да - удалить это поле
cache_get_field_content(i, "nickname", name1, MysqlConnect, MAX_PLAYER_NAME);
}
else
{
name2[0] = EOS;
cache_get_field_content(i, "nickname", name2, MysqlConnect, MAX_PLAYER_NAME);
}
}
SKIP_CYCLE:
printf("На выходе получаем: Фракция 6: %s | Фракция 7: %s", name1, name2);
return 1;
}
Не ругайтесь, просто сразу не понял, теперь подчитавши, стал на 0.0000000001 процент умнее (страшно использовать то что не разу не делал, и не понимал)
Не ругайтесь, просто сразу не понял, теперь подчитавши, стал на 0.0000000001 процент умнее (страшно использовать то что не разу не делал, и не понимал)
Я не ругаюсь, тон речи письмом сложно передать (:
Так оно так-бы и было))
У тебя без playerid
И проверку должна быть такой:
if (!IsPlayerConnected(playerid))
cache_get_field_content(i, "nickname", name, MysqlConnect, MAX_PLAYER_NAME);
else
GetPlayerName(playerid, name, MAX_PLAYER_NAME);
Но по сути проверку с бд должно хватать
Powered by vBulletin® Version 4.2.0 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot