PDA

Просмотр полной версии : [Вопрос] Мысли по оптимизации кода



Сергей
07.02.2019, 17:41
Доброго времени суток.
Написал систему одну, ну и вижу, что код получился, мягко говоря "не очень"
Может будут у кого-то мысли по его оптимизации?

Запрос в БД


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;
}

m1n1vv
07.02.2019, 21:14
Что первое в голову пришло


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;
}

Сергей
07.02.2019, 21:22
Что первое в голову пришло


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 = Нет
В твоём случае, моя цель достигнута не будет)

Спасибо большое за Вашу мысль оптимизации)

DeimoS
08.02.2019, 00:23
Опиши структуру таблицы (названия столбцов + какие данные хранятся и в каких количествах), а так же то, какой результат ты хочешь получить.

Если ты просто ищешь двух игроков по определённому условию, то гораздо оптимизированнее будет сделать выборку в запросе, а не выгружать все данные и делать выборку на стороне сервера.

Сергей
08.02.2019, 02:56
Опиши структуру таблицы (названия столбцов + какие данные хранятся и в каких количествах), а так же то, какой результат ты хочешь получить.

Если ты просто ищешь двух игроков по определённому условию, то гораздо оптимизированнее будет сделать выборку в запросе, а не выгружать все данные и делать выборку на стороне сервера.

Я хотел получить двух игроков, просто далее, я намерен использовать диалог, где буду использовать их ники, если же, игроков с данными лидерками найдено не будет, вместо ника в диалоговом окне будет показано "Нет"
Названия столбцов сами за себя говорят.

m1n1vv
08.02.2019, 04:23
"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;
}

m1n1vv
08.02.2019, 17:11
"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;
}

Сергей
08.02.2019, 17:36
"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 фракции?

m1n1vv
08.02.2019, 17:45
Так а если нужны конкретно лидеры 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;
}

Сергей
08.02.2019, 18:20
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 фракцией.
НО, если игроков с такой лидеркой не нашло, я присваиваю переменной "Нет"

seriu
08.02.2019, 21:04
"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)

m1n1vv
08.02.2019, 21:41
Снова не до поняли, вот в моём примере я сделал вот как:
Ищу лидеров фракций.
Далее отсеиваю игроков, у которых ячейка p_leader равна 0
Далее, если нашло лидера Фракции 6 - Я получаю его имя, ровно так-же и с 7 фракцией.
НО, если игроков с такой лидеркой не нашло, я присваиваю переменной "Нет"

А тогда зачем проверка, находится игрок на сервере или нет?
Взяв твой код. Откуда online_pl берет ид игрока для GetPlayerName?

Сергей
08.02.2019, 22:08
При авторизации, регистрации записывается ид игрока туда

m1n1vv
09.02.2019, 01:04
При авторизации, регистрации записывается ид игрока туда

Как оно записывается в переменную, если она не глобальная? Тогда может лучше так?


mysql_function_query(MysqlConnect, "SELECT `p_leader`,`online_status`,`nickname` FROM `"TABLE_ACC"`", true, "OnCheckLEADCallBack","i", playerid);

forward OnCheckLEADCallBack(playerid);
public OnCheckLEADCallBack(playerid)

Сергей
09.02.2019, 02:49
Как оно записывается в переменную, если она не глобальная? Тогда может лучше так?


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 фракцией.
НО, если игроков с такой лидеркой не нашло, я присваиваю переменной "Нет"

Сергей
09.02.2019, 03:33
Вот, что снова, так сказать получилось по моей задумке:



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 раз лучше, но, не пойму как...

А получение онлайн статуса теперь в принципе не нужно. Так-как изменил задумку данной фичи)

UnO
09.02.2019, 04:39
Тебе двое людей выше уже сказали, что выборку лучше делать на стороне субд, чем циклом вручную.



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;
}

Сергей
09.02.2019, 05:27
Тебе двое людей выше уже сказали, что выборку лучше делать на стороне субд, чем циклом вручную.



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 процент умнее (страшно использовать то что не разу не делал, и не понимал)

UnO
09.02.2019, 05:42
Не ругайтесь, просто сразу не понял, теперь подчитавши, стал на 0.0000000001 процент умнее (страшно использовать то что не разу не делал, и не понимал)

Я не ругаюсь, тон речи письмом сложно передать (:

m1n1vv
09.02.2019, 11:57
Так оно так-бы и было))

У тебя без playerid

И проверку должна быть такой:

if (!IsPlayerConnected(playerid))
cache_get_field_content(i, "nickname", name, MysqlConnect, MAX_PLAYER_NAME);
else
GetPlayerName(playerid, name, MAX_PLAYER_NAME);

Но по сути проверку с бд должно хватать