Сообщение от
SooBad
Да, разницы никакой нет. Это вполне очевидно.
Всё упирается лишь в восприятие кода и совместимости. (Некоторые не знают про данный оператор, либо используют pawn 4.x).
Поэтому, тут дело случая. Опасность применения вышеуказанных инструкций отсутствует.
Равно как и отсутствует хоть мало-мальски внятная причина обфусцировать свой код. Зато проглядывается намерение устроить показуху.
Справедливости ради стоит отметить, что возможность оптимизировать код с помощью #emit есть, но она совсем небольшая: если преобразовать выражение "degr_count |= 0b11 << (0b10 * i);", то в последующем коде "temp = value & degr_count" можно избежать лишнюю загрузку значения из degr_count в один из регистров.
Также хотелось бы отдельно указать на "плюсы" реализации, которые тоже очень и очень сомнительны.
Не требует преобразований целочисленных значений в вещественные, в отличие от того же floatsqroot.
Если вы видите в этом препятствие производительности, то функция int_sqrt потребует ещё больше ресурсов.
Чтобы не быть голословным, предоставлю тест производительности.
Профайлер: http://pro-pawn.ru/showthread.php?12585
Настройки:
Открыть/закрыть
PHP код:
/*======== Настройки =========================================================*/
const PROFILER_ITERATIONS_MAJOR = 10_000;
const PROFILER_ITERATIONS_MINOR = 100;
new const code_snippets_names[2][] =
{
{"int_sqrt"},
{"float+floatsqroot+floatround"}
};
stock int_sqrt(value)
{
new
result,
temp,
degr_count;
for(new i = 3; i >= 0; i--)
{
degr_count |= 0b11 << (0b10 * i);
#emit load.s.pri value
#emit load.s.alt degr_count
#emit and
#emit stor.s.pri temp
returning:
result ^= 0b1 << i;
if(temp < (result * result))
goto returning;
}
return result;
}
#define Prerequisites();\
static i;
const TEST_MIN_VALUE = 1, TEST_MAX_VALUE = 100, TEST_STEP = 5;
#define CodeSnippet0();\
for (i = TEST_MIN_VALUE; i <= TEST_MAX_VALUE; i += TEST_STEP)\
int_sqrt(i);
#define CodeSnippet1();\
for (i = TEST_MIN_VALUE; i <= TEST_MAX_VALUE; i += TEST_STEP)\
floatround(floatsqroot(float(i)), floatround_tozero);
/*======== Конец настроек ===================================================*/
Вывод:
Код:
Тестирование: <int_sqrt> vs <float+floatsqroot+floatround>
Режим: интерпретируемый, 10000x100 итераций.
int_sqrt: 15672
float+floatsqroot+floatround: 1708
Код:
Тестирование: <int_sqrt> vs <float+floatsqroot+floatround>
Режим: с JIT-компиляцией, 10000x100 итераций.
int_sqrt: 1365
float+floatsqroot+floatround: 880
Связка "float+floatsqroot+floatround" требует вызова трёх нативных функций, но затраты окупаются за счёт быстрого вычисления корня математическим сопроцессором, что ничуть не удивительно: он специально создан для подобных задач.
При написании независимых систем вам не придётся подгружать библиотеку float для подсчётов, с применением лишь одной функции.
"Независимых систем"? Кому в здравом уме нужна будет независимость от библиотеки float?
У неё слишком обширный набор функций? Нет, в ней только основные функции для работы с вещ. числами. Возможно, этих функций там даже слишком мало - не хватает обратных тригонометрических функций, которые реализованы отдельно в SA-MP.
Ок, может быть это чья-то сторонняя библиотека, которую не хотелось бы лишних раз таскать за собой? Нет, это один из стандартных модулей Pawn AMX.
Тогда, может модуль amxfloat специфичен для какой-то программно-аппаратной платформы и имеет проблемы с переносимостью? И снова мимо. Это всего лишь вещественные числа, которые есть практически на любой аппаратной платформе (кроме, разве что, каких-то малоизвестных и узкоспециализированных), а потому можно даже не задумываться о переносимости модуля - он портируется так же просто, как и остальные. К слову, куда больше проблем с портированием может возникнуть у модулей amxfile, amxcons и amxdgram (неполноценная стандартная библиотека C, нетривиальный API для работы с консолью, etc.), так что amxfloat здесь, наоборот, самый простой.
Единственное удобство int_sqrt, которое мне приходит в голову, так это более короткая запись. Такое себе преимущество, поскольку оно легко достигается с помощью макросов.
PHP код:
#define int_sqrt(%0)\
floatround(floatsqroot(float(%0)), floatround_tozero)