PDA

Просмотр полной версии : [Вопрос] Проверка



kushichka
10.07.2016, 23:46
Имеются координаты машины в гараже, если он есть(гараж):

Float:CarInGarageX, CarInGarageY, CarInGarageZ;
И на улице, для телепортации с гаража или если гаража нет:

Float:CarOutGarageX, CarOutGarageY, CarOutGarageZ;
Как лучше будет проверять наличие гаража у дома?
Создать еще одну переменную Garage и при установке дома задавать ей значение и, соответственно, через нее проверять:

if(Garage(houseid) = 1) return print("Гараж есть");
Или забивать координаты позиции машины в доме нулями и через них проверять, если это возможно. Пустые поля нельзя же оставлять.
Для этого нужно создавать несколько стоков, в одном дать запрос на считывание с базы и передать на обработку в другой, который уже и вернет ответ. А в одной функции этого, я так понимаю, сделать нельзя?

Я понимаю что проще создать переменную не париться, но можно ли как-то реализовать без нее?

DeimoS
11.07.2016, 00:00
Для этого нужно создавать несколько стоков, в одном дать запрос на считывание с базы и передать на обработку в другой, который уже и вернет ответ. А в одной функции этого, я так понимаю, сделать нельзя?

О каком стоке идёт речь - не совсем понимаю.
Проще всего несуществующим гаражам задавать нереальные координаты (хотя бы нулевые) и сверять, например, первую

if(!floatcmp(переменная_с_х, 0.0)) return гаража нет;

kushichka
11.07.2016, 00:05
О каком стоке идёт речь - не совсем понимаю.
Проще всего несуществующим гаражам задавать нереальные координаты (хотя бы нулевые) и сверять, например, первую

if(!floatcmp(переменная_с_х, 0.0)) return гаража нет;

А, я подумал что нужно сначала загрузить информацию с бд(для этого нужен был сток), а потом уже проверять, хотя вся информация загружается при загрузке сервера. Но за такую конструкцию отдельное спасибо, не знал о таком floatcmp.

Nexius_Tailer
11.07.2016, 00:10
А, я подумал что нужно сначала загрузить информацию с бд(для этого нужен был сток), а потом уже проверять, хотя вся информация загружается при загрузке сервера. Но за такую конструкцию отдельное спасибо, не знал о таком floatcmp.
stock указывает лишь то, что переменная/функция возможно не будет использована (чтобы варнинга в таком случае не было). Вот к чему тот вопрос был, это функциями называют.
П.с. сравнение координат напрямую должно быть быстрее (просто сверять в условии), чем ещё вызывать функцию из сервера, хотя не столь важно.

DeimoS
11.07.2016, 00:29
сравнение координат напрямую должно быть быстрее (просто сверять в условии), чем ещё вызывать функцию из сервера, хотя не столь важно.
Уже давно проводил тест

// Profiler v1.2 (copyright (c) 2014-2015 Daniel_Cortez) \\ Pro - Pawn . ru
// Условия использования данного кода: http://pro - pawn . ru/showthread.php?12585

/*======== Настройки =========================================================*/
// Кол-во итераций в циклах.
const PROFILER_ITERATIONS_MAJOR = 10_000;
const PROFILER_ITERATIONS_MINOR = 1_000;
// Названия отрывков кода.
new const code_snippets_names[2][] =
{
{"if"},
{"floatcmp"}
};

// Здесь вы можете объявить переменные, используемые в профилируемых отрывках кода
// и выполнить некоторые действия непосредственно перед профилированием.
#define Prerequisites(); \
new Float:last_vehicle_health[MAX_PLAYERS], Float:carhp = 200.0;\
last_vehicle_health[11] = 250.0;
/*
Собственно, сами отрывки кода, которые нужно тестировать.
Если код состоит из нескольких строк, переносите их обратным слэшем.
Пример:
#define CodeSnippet1();\
DoSomething();\
DoSomethingElse();
*/
#define CodeSnippet0();\
if(last_vehicle_health[11] > carhp) {}

#define CodeSnippet1();\
if(floatcmp(last_vehicle_health[11], carhp) == 1) {}
// <ваш код>
/*======== Конец настроек ===================================================*/



// Не рекомендую изменять следующий код, если вы в нём не разбираетесь.
#tryinclude <a_samp>
#include <jit>
#if defined _samp_included
#define LINE_BREAK ""
#else
#define LINE_BREAK "\n"
#include <core>
#include <time>
#define GetTickCount() tickcount()
#endif

#define _PROFILE_START(%0)\
t[%0] = GetTickCount();\
for (j = 0; j < PROFILER_ITERATIONS_MINOR; ++j)\
{
#define _PROFILE_END(%0)\
}\
t[%0] = GetTickCount()-t[%0];

#if defined _samp_included
#define PROFILE_START(%0); _PROFILE_START(%0)
#define PROFILE_END(%0); _PROFILE_END(%0)
#else
#define PROFILE_START(%0); _PROFILE_START(%0)
#define PROFILE_END(%0); if ((_PROFILE_END(%0)) < 0) {--i; continue;}
#endif

#define CODE_SNIPPET_EXISTS(%0)\
(sizeof(code_snippets_names) >= ((%0) + 1)) && (defined CodeSnippet%0)


new code_snippets_time[sizeof(code_snippets_names)] = {0, ...};

main()
{
new i, j, t[sizeof(code_snippets_names)];
#emit zero.pri
#emit lctrl 7
#emit stor.s.pri i
#if CODE_SNIPPET_EXISTS(2)
static const ending[] =
#if (sizeof(code_snippets_names) <= 4)
"ка";
#else
"ков";
#endif
printf(
"Тестирование: %d отрыв%s кода." LINE_BREAK,
sizeof(code_snippets_names), ending
);
#else
printf(
"Тестирование: <%s> vs <%s>" LINE_BREAK,
code_snippets_names[0], code_snippets_names[1]
);
#endif
static const JIT_status_strings[2][] =
{"интерпретируемый", "с JIT-компиляцией"};
printf(
"Режим: %s, %dx%d итераций.\a" LINE_BREAK,
JIT_status_strings[i],
PROFILER_ITERATIONS_MAJOR, PROFILER_ITERATIONS_MINOR
);
Prerequisites();
for (i = 0; i < PROFILER_ITERATIONS_MAJOR; ++i)
{
PROFILE_START(0);
CodeSnippet0();
PROFILE_END(0);
PROFILE_START(1);
CodeSnippet1();
PROFILE_END(1);
#if CODE_SNIPPET_EXISTS(2)
PROFILE_START(2);
CodeSnippet2();
PROFILE_END(2);
#endif
#if CODE_SNIPPET_EXISTS(3)
PROFILE_START(3);
CodeSnippet3();
PROFILE_END(3);
#endif
#if CODE_SNIPPET_EXISTS(4)
PROFILE_START(4);
CodeSnippet4();
PROFILE_END(4);
#endif
#if CODE_SNIPPET_EXISTS(5)
PROFILE_START(5);
CodeSnippet5();
PROFILE_END(5);
#endif
#if CODE_SNIPPET_EXISTS(6)
PROFILE_START(6);
CodeSnippet6();
PROFILE_END(6);
#endif
#if CODE_SNIPPET_EXISTS(7)
PROFILE_START(7);
CodeSnippet7();
PROFILE_END(7);
#endif
#if CODE_SNIPPET_EXISTS(8)
PROFILE_START(8);
CodeSnippet8();
PROFILE_END(8);
#endif
#if CODE_SNIPPET_EXISTS(9)
PROFILE_START(9);
CodeSnippet9();
PROFILE_END(9);
#endif
#if CODE_SNIPPET_EXISTS(10)
PROFILE_START(10);
CodeSnippet10();
PROFILE_END(10);
#endif
#if CODE_SNIPPET_EXISTS(11)
PROFILE_START(11);
CodeSnippet11();
PROFILE_END(11);
#endif
#if CODE_SNIPPET_EXISTS(12)
PROFILE_START(12);
CodeSnippet12();
PROFILE_END(12);
#endif
#if CODE_SNIPPET_EXISTS(13)
PROFILE_START(13);
CodeSnippet13();
PROFILE_END(13);
#endif
#if CODE_SNIPPET_EXISTS(14)
PROFILE_START(14);
CodeSnippet14();
PROFILE_END(14);
#endif
#if CODE_SNIPPET_EXISTS(15)
PROFILE_START(15);
CodeSnippet15();
PROFILE_END(15);
#endif
for (j = 0; j < sizeof(code_snippets_names); ++j)
code_snippets_time[j] += t[j];
}
for (i = 0; i < sizeof(code_snippets_names); ++i)
printf(
"%s: %d" LINE_BREAK,
code_snippets_names[i], code_snippets_time[i]
);
print("\a\a" LINE_BREAK);
}

http://i.imgur.com/lxTtdFd.png

http://i.imgur.com/MG4AHnQ.png


Такая разница в скорости не на все функции с вещественными числами распространяется. Точно уже не помню какие выигрывают в скорости, но точно не все

Nexius_Tailer
11.07.2016, 00:32
Уже давно проводил тест

// Profiler v1.2 (copyright (c) 2014-2015 Daniel_Cortez) \\ Pro - Pawn . ru
// Условия использования данного кода: http://pro - pawn . ru/showthread.php?12585

/*======== Настройки =========================================================*/
// Кол-во итераций в циклах.
const PROFILER_ITERATIONS_MAJOR = 10_000;
const PROFILER_ITERATIONS_MINOR = 1_000;
// Названия отрывков кода.
new const code_snippets_names[2][] =
{
{"if"},
{"floatcmp"}
};

// Здесь вы можете объявить переменные, используемые в профилируемых отрывках кода
// и выполнить некоторые действия непосредственно перед профилированием.
#define Prerequisites(); \
new Float:last_vehicle_health[MAX_PLAYERS], Float:carhp = 200.0;\
last_vehicle_health[11] = 250.0;
/*
Собственно, сами отрывки кода, которые нужно тестировать.
Если код состоит из нескольких строк, переносите их обратным слэшем.
Пример:
#define CodeSnippet1();\
DoSomething();\
DoSomethingElse();
*/
#define CodeSnippet0();\
if(last_vehicle_health[11] > carhp) {}

#define CodeSnippet1();\
if(floatcmp(last_vehicle_health[11], carhp) == 1) {}
// <ваш код>
/*======== Конец настроек ===================================================*/



// Не рекомендую изменять следующий код, если вы в нём не разбираетесь.
#tryinclude <a_samp>
#include <jit>
#if defined _samp_included
#define LINE_BREAK ""
#else
#define LINE_BREAK "\n"
#include <core>
#include <time>
#define GetTickCount() tickcount()
#endif

#define _PROFILE_START(%0)\
t[%0] = GetTickCount();\
for (j = 0; j < PROFILER_ITERATIONS_MINOR; ++j)\
{
#define _PROFILE_END(%0)\
}\
t[%0] = GetTickCount()-t[%0];

#if defined _samp_included
#define PROFILE_START(%0); _PROFILE_START(%0)
#define PROFILE_END(%0); _PROFILE_END(%0)
#else
#define PROFILE_START(%0); _PROFILE_START(%0)
#define PROFILE_END(%0); if ((_PROFILE_END(%0)) < 0) {--i; continue;}
#endif

#define CODE_SNIPPET_EXISTS(%0)\
(sizeof(code_snippets_names) >= ((%0) + 1)) && (defined CodeSnippet%0)


new code_snippets_time[sizeof(code_snippets_names)] = {0, ...};

main()
{
new i, j, t[sizeof(code_snippets_names)];
#emit zero.pri
#emit lctrl 7
#emit stor.s.pri i
#if CODE_SNIPPET_EXISTS(2)
static const ending[] =
#if (sizeof(code_snippets_names) <= 4)
"ка";
#else
"ков";
#endif
printf(
"Тестирование: %d отрыв%s кода." LINE_BREAK,
sizeof(code_snippets_names), ending
);
#else
printf(
"Тестирование: <%s> vs <%s>" LINE_BREAK,
code_snippets_names[0], code_snippets_names[1]
);
#endif
static const JIT_status_strings[2][] =
{"интерпретируемый", "с JIT-компиляцией"};
printf(
"Режим: %s, %dx%d итераций.\a" LINE_BREAK,
JIT_status_strings[i],
PROFILER_ITERATIONS_MAJOR, PROFILER_ITERATIONS_MINOR
);
Prerequisites();
for (i = 0; i < PROFILER_ITERATIONS_MAJOR; ++i)
{
PROFILE_START(0);
CodeSnippet0();
PROFILE_END(0);
PROFILE_START(1);
CodeSnippet1();
PROFILE_END(1);
#if CODE_SNIPPET_EXISTS(2)
PROFILE_START(2);
CodeSnippet2();
PROFILE_END(2);
#endif
#if CODE_SNIPPET_EXISTS(3)
PROFILE_START(3);
CodeSnippet3();
PROFILE_END(3);
#endif
#if CODE_SNIPPET_EXISTS(4)
PROFILE_START(4);
CodeSnippet4();
PROFILE_END(4);
#endif
#if CODE_SNIPPET_EXISTS(5)
PROFILE_START(5);
CodeSnippet5();
PROFILE_END(5);
#endif
#if CODE_SNIPPET_EXISTS(6)
PROFILE_START(6);
CodeSnippet6();
PROFILE_END(6);
#endif
#if CODE_SNIPPET_EXISTS(7)
PROFILE_START(7);
CodeSnippet7();
PROFILE_END(7);
#endif
#if CODE_SNIPPET_EXISTS(8)
PROFILE_START(8);
CodeSnippet8();
PROFILE_END(8);
#endif
#if CODE_SNIPPET_EXISTS(9)
PROFILE_START(9);
CodeSnippet9();
PROFILE_END(9);
#endif
#if CODE_SNIPPET_EXISTS(10)
PROFILE_START(10);
CodeSnippet10();
PROFILE_END(10);
#endif
#if CODE_SNIPPET_EXISTS(11)
PROFILE_START(11);
CodeSnippet11();
PROFILE_END(11);
#endif
#if CODE_SNIPPET_EXISTS(12)
PROFILE_START(12);
CodeSnippet12();
PROFILE_END(12);
#endif
#if CODE_SNIPPET_EXISTS(13)
PROFILE_START(13);
CodeSnippet13();
PROFILE_END(13);
#endif
#if CODE_SNIPPET_EXISTS(14)
PROFILE_START(14);
CodeSnippet14();
PROFILE_END(14);
#endif
#if CODE_SNIPPET_EXISTS(15)
PROFILE_START(15);
CodeSnippet15();
PROFILE_END(15);
#endif
for (j = 0; j < sizeof(code_snippets_names); ++j)
code_snippets_time[j] += t[j];
}
for (i = 0; i < sizeof(code_snippets_names); ++i)
printf(
"%s: %d" LINE_BREAK,
code_snippets_names[i], code_snippets_time[i]
);
print("\a\a" LINE_BREAK);
}

http://i.imgur.com/lxTtdFd.png

http://i.imgur.com/MG4AHnQ.png


Такая разница в скорости не на все функции с вещественными числами распространяется. Точно уже не помню какие выигрывают в скорости, но точно не все
А, ну ок, буду знать.

ziggi
11.07.2016, 00:35
Если по теме вопроса, то я считаю, что лучше создать новую переменную. Ведь, чисто теоретически, настоящие координаты гаража могут быть равны 0.0, вероятность этого крайне мала, но она есть.


А, я подумал что нужно сначала загрузить информацию с бд(для этого нужен был сток), а потом уже проверять, хотя вся информация загружается при загрузке сервера. Но за такую конструкцию отдельное спасибо, не знал о таком floatcmp.

Логика использования floatcmp мне не понятна. Проще использовать привычные всем операторы сравнения ==, != и т.п..

if(!переменная_с_х != 0.0) return гаража нет;

Тем более на скорость работы это никак не повлияет, убедиться в этом можно открыв файл float.inc из стандартного набора инклудов.

stock bool:operator!=(Float:oper1, Float:oper2)
return floatcmp(oper1, oper2) != 0;

UPD: Интересный тест. Получается, что Pawn создаёт дополнительную функцию-обёртку для каждого оператора.

DeimoS
11.07.2016, 00:55
Если по теме вопроса, то я считаю, что лучше создать новую переменную. Ведь, чисто теоретически, настоящие координаты гаража могут быть равны 0.0, вероятность этого крайне мала, но она есть.

Имхо, если система не уйдёт никуда, дальше собственного пользования и ты уверен, что нулевые координаты никак не попадут в массив - проще напрямую использовать. И память экономим, и лишних переменных, значения коротых нужно держать в голове, меньше. Получится как с проверкой на валидность ID (я о макросе INVALID_PLAYER_ID. Хоть данное значение и не везде используется, но суть та же: есть значение, которое 100% никогда не будет использоваться и по нему ориентируется).

Кстати, не обязательно приравнивать к "0.0". Можно взять какое-нибудь заграничное "999999999.0". Слишком больших координат SA-MP не переносит (начинаются глюки с созданными сервером объектами и т.п.), поэтому "предел" найти легко.

P.S. Вполне возможно, что я где-то в тесте налажал. Я сам тогда удивился, что так вышло.

kushichka
11.07.2016, 00:57
Если по теме вопроса, то я считаю, что лучше создать новую переменную. Ведь, чисто теоретически, настоящие координаты гаража могут быть равны 0.0, вероятность этого крайне мала, но она есть.



Логика использования floatcmp мне не понятна. Проще использовать привычные всем операторы сравнения ==, != и т.п..

if(!переменная_с_х != 0.0) return гаража нет;

Тем более на скорость работы это никак не повлияет, убедиться в этом можно открыв файл float.inc из стандартного набора инклудов.

stock bool:operator!=(Float:oper1, Float:oper2)
return floatcmp(oper1, oper2) != 0;

UPD: Интересный тест. Получается, что Pawn создаёт дополнительную функцию-обёртку для каждого оператора.

то есть проще будет сравнивать одну из координату, к примеру X с 0.0, чем использовать floatcm? А еще проще создать переменную и не парить мозг?)