PDA

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



ALIT13
11.01.2016, 15:46
Добрый день вот я парня заказал Оптимизацию мода
у меня был вариант

CMD:mm ( playerid )
{
new listitems[] = "\
{1D8DCF}[1]{FFFFFF}. » Моя статистика\
\n{1D8DCF}[2]{FFFFFF}. » Репорт\
\n{1D8DCF}[3]{FFFFFF}. » Мои команды\
\n{1D8DCF}[4]{FFFFFF}. » Личные настройки\
\n{1D8DCF}[5]{FFFFFF}. » Мои Возможности\
\n{1D8DCF}[6]{FFFFFF}. » Донат";
new lvlexp[80];
new level = PInfo[playerid][pLevel];
format(lvlexp,70,"Личное меню | Лвл: %d | WARN: ",level);
ShowPlayerDialog(playerid, 71, DIALOG_STYLE_LIST, lvlexp, listitems, "Выбрать", "Закрыть");
return true;
}

А пользователь сменил на

#define MAX_MAIN 6
new mainmenu[MAX_MAIN][14] =
{"~ Моя статистика",
"~ Репорт",
"~ Мои команды",
"~ Личные настройки",
"~ Мои Возможности",
"~ Донат",}
;

stock DialogMain(playerid)
{
new mes[150];
for(new i;i < MAX_MAIN;i++)
{
format(mes,sizeof(mes),"{ffffff}%s%s\n",mes,mainme nu[i]);
}
SPD(playerid,64,DIALOG_STYLE_LIST,"{C7001B}Меню персонажа",mes,"Выбор","Отмена");
return true;
}
Разница есть ?

VVWVV
11.01.2016, 16:27
Как минимум, данную команду можно сделать более производительнее, но если говорить о данных вариантах, то в первом будет всегда вызываться новый массив (listitems), а после выполнения будет уничтожаться (хотя, можно было сделать с помощью static. Для того, чтобы данный массив заносился в сегмент с памятью). Использование цикла с функцией format (во втором варианте) — очень трагично (в идеале, можно было сделать отправку аргументов с помощью ассемблера, но это также трагично, ибо делать это не так уж просто). Если массив используется меньше двух раз, например, один, то его следует занести в блок с данной функцией (хотя, можно этого не делать).
В обоих вариантах нет подсчёта форматируемой строки, т.е. берутся какие-то магические цифры (именно из-за них могут быть проблемы).

Информация для ТС: Всю статическую информацию можно упаковывать.

P.S.: пользователь, которые дал вам такую «оптимизированную» функцию — сам ничего не смыслит в программировании, ибо это не оптимизация (хотя, в кругу г-и его код сочтут за оптимизацию, что и отличает данный сайт от Pro-Pawn.Ru).


Мой вариант:

CMD:mm(playerid, params[])
{
static const
listitems[] = !"{1D8DCF}[1]{FFFFFF}. » Моя статистика"\
"\n{1D8DCF}[2]{FFFFFF}. » Репорт"\
"\n{1D8DCF}[3]{FFFFFF}. » Мои команды"\
"\n{1D8DCF}[4]{FFFFFF}. » Личные настройки"\
"\n{1D8DCF}[5]{FFFFFF}. » Мои Возможности"\
"\n{1D8DCF}[6]{FFFFFF}. » Донат";

// ОШИБКА: Для того, чтобы функция strcat работала правильно, во второй аргумент требуется указывать строку.
// static title[64 char] = !"Личное меню | Уровень: ";
// strcat(title, PInfo[playerid][pLevel]);
// Переработанный вариант
static const title[] = "Личное меню | Уровень: %d";
new frmStr[sizeof title + (-2 + 2)];
format(frmStr, sizeof frmStr, title, PInfo[playerid][pLevel]);

// Другой вариант (использование valstr). - Не рекомендуется.
// static title[64 char] = !"Личное меню | Уровень: ";
// new buff[3 char];
// valstr(buff, PInfo[playerid][pLevel], true);
// strcat(title, buff);
return ShowPlayerDialog(playerid, 71, DIALOG_STYLE_LIST,
title, listitems,
!"Выбрать", !"Закрыть");
}
Лимиты в SA:MP (https://wiki.sa-mp.com/wiki/%D0%9B%D0%B8%D0%BC%D0%B8%D1%82%D1%8B)

Desulaid
11.01.2016, 16:29
Я вообще так сделал бы.


COMMAND:mm(playerid, params[])
{
static body[] = !"\
{1D8DCF}[1]{FFFFFF}. » Моя статистика\
\n{1D8DCF}[2]{FFFFFF}. » Репорт\
\n{1D8DCF}[3]{FFFFFF}. » Мои команды\
\n{1D8DCF}[4]{FFFFFF}. » Личные настройки\
\n{1D8DCF}[5]{FFFFFF}. » Мои Возможности\
\n{1D8DCF}[6]{FFFFFF}. » Донат";

static const title[] = !"Личное меню | Лвл: %d";
new format_title[sizeof(title) + (-2) + 2 + 1];
format(format_title, sizeof(format_title), title, PInfo[playerid][pLevel]);

ShowPlayerDialog(playerid, 71, DIALOG_STYLE_LIST, format_title, body, !"Выбрать", !"Закрыть");
return 1;
}

Ваш вариант от части лучше, ну как по мне. Так как ваши массивы/переменные объявлены локально > из стэка при завершении работы команды они удалятся, но и при вызове снова воссаздадуться. Его же вариант - укоротить код и все, я называю это "оптимизация для глаз". Его массив будет висеть в стэке все время, а ведь он понадобится нам один раз. Да и овер раз форматировать текст, который вообще никак не изменяется - бред.

ALIT13
11.01.2016, 16:29
Как минимум, данную команду можно сделать более производительнее, но если говорить о данных вариантах, то в первом будет всегда вызываться новый массив (listitems), а после выполнения будет уничтожаться (хотя, можно было сделать с помощью static. Для того, чтобы данный массив заносился в сегмент с памятью). Использование цикла с функцией format (во втором варианте) — очень трагично (в идеале, можно было сделать отправку аргументов с помощью ассемблера, но это также трагично, ибо делать это не так уж просто). Если массив используется меньше двух раз, например, один, то его следует занести в блок с данной функцией (хотя, можно этого не делать).
В обоих вариантах нет подсчёта форматируемой строки, т.е. берутся какие-то магические цифры (именно из-за них могут быть проблемы).

Информация для ТС: Всю статическую информацию можно упаковывать.

P.S.: пользователь, которые дал вам такую «оптимизированную» функцию — сам ничего не смыслит в программировании, ибо это не оптимизация (хотя, в кругу г-и его код сочтут за оптимизацию, что и отличает данный сайт от Pro-Pawn.Ru).

напиши свой вариант

VVWVV
11.01.2016, 16:41
напиши свой вариант

Обновил своё первое сообщение.

ALIT13
11.01.2016, 16:50
Я вообще так сделал бы.


COMMAND:mm(playerid, params[])
{
static body[] = "\
{1D8DCF}[1]{FFFFFF}. » Моя статистика\
\n{1D8DCF}[2]{FFFFFF}. » Репорт\
\n{1D8DCF}[3]{FFFFFF}. » Мои команды\
\n{1D8DCF}[4]{FFFFFF}. » Личные настройки\
\n{1D8DCF}[5]{FFFFFF}. » Мои Возможности\
\n{1D8DCF}[6]{FFFFFF}. » Донат";

static const title[] = "Личное меню | Лвл: %d";
new format_title[sizeof(title) + (-2) + 2 + 1];
format(format_title, sizeof(format_title), title, PInfo[playerid][pLevel]);

ShowPlayerDialog(playerid, 71, DIALOG_STYLE_LIST, format_title, body, "Выбрать", "Закрыть");
return 1;
}

Ваш вариант от части лучше, ну как по мне. Так как ваши массивы/переменные объявлены локально > из стэка при завершении работы команды они удалятся, но и при вызове снова воссаздадуться. Его же вариант - укоротить код и все, я называю это "оптимизация для глаз". Его массив будет висеть в стэке все время, а ведь он понадобится нам один раз. Да и овер раз форматировать текст, который вообще никак не изменяется - бред.

Для чего 2 + 1
new format_title[sizeof(title) + (-2) + 2 + 1];

Profyan
11.01.2016, 16:50
Его массив будет висеть в стэке все время, а ведь он понадобится нам один раз.

Почему в стеке.Он объявлен глобально,не?

Desulaid
11.01.2016, 17:23
strcat(title, PInfo[playerid][pLevel]);

Мы не можем так сделать, так как strcat строки сцепляет, а тут строка и число. Да и static const не вариант, а массив title уж очень большой, я не думаю, что все 63 ячейки будут забиты (нули не в счет!), я бы предложил 25-26 ячеек.


Для чего 2 + 1
new format_title[sizeof(title) + (-2) + 2 + 1];

-2 символа из строка - %d (это два символа, при форматировании они как одно целое)+ 2 цифры, которые заменят это место, ну и + 1 на нуль символ


Почему в стеке.Он объявлен глобально,не?

Дак массивы не удаляются, если глобально объявлены. Они будут все время занимать n-часть памяти.

VVWVV
11.01.2016, 17:52
Мы не можем так сделать, так как strcat строки сцепляет, а тут строка и число. Да и static const не вариант, а массив title уж очень большой, я не думаю, что все 63 ячейки будут забиты (нули не в счет!), я бы предложил 25-26 ячеек.

Не учёл. Использовал символ # для перевода в строку при тестировании; остаётся только метод с format (хотя, можно сделать с помощью valstr для перевода значения в строку).
Не очень люблю магические цифры. Можно вычислить длину строки, как это сделал ты.

А почему static const не вариант? Мы же не будем менять содержимое данного массива.

Спасибо, что заметил мою ошибку.

Daniel_Cortez
11.01.2016, 18:46
Дак массивы не удаляются, если глобально объявлены. Они будут все время занимать n-часть памяти.
Но не в стеке же, а в секции данных. В стеке обычно находятся локальные переменные, объявляемые в функциях с помощью ключевого слова new.

P.S.: Оставил бы здесь свой вариант команды, но он во многом будет совпадать с вариантом VVWVV, разве что за исключением названий переменных.