Накидал тут свой тест производительности обычных переменных на Pawn и PVar'ов.
PHP код:
CMD:profile(playerid, params[])
{
const PROFILE_ITERATIONS_MAJOR = 10_000,
PROFILE_ITERATIONS_MINOR = 100;
const NUM_PVARS = 100;
static const pvar_name_prefix[] = "pvar_%03d";
static pvar_name[sizeof(pvar_name_prefix) + (- 4 + 3)];
static arr[2], x;
for (i = 0; i < NUM_PVARS; ++i)
{
format(pvar_name, sizeof(pvar_name), pvar_name_prefix, i);
SetPVarInt(playerid, pvar_name, 0);
}
static x, y;
static t, t1, t2, t3, t4;
t1 = 0, t2 = 0, t3 = 0, t4 = 0;
for (i = PROFILE_ITERATIONS_MAJOR; i-- != 0; )
{
t = GetTickCount();
for (j = PROFILE_ITERATIONS_MINOR; j-- != 0; )
y = x;
t1 += GetTickCount() - t;
t = GetTickCount();
for (j = PROFILE_ITERATIONS_MINOR; j-- != 0; )
y = GetPVarInt(playerid, pvar_name);
t2 += GetTickCount() - t;
t = GetTickCount();
for (j = PROFILE_ITERATIONS_MINOR; j-- != 0; )
x = 42;
t3 += GetTickCount() - t;
t = GetTickCount();
for (j = PROFILE_ITERATIONS_MINOR; j-- != 0; )
SetPVarInt(playerid, pvar_name, 42);
t4 += GetTickCount() - t;
}
new results_buf[128 + 1];
new jit_enabled;
#emit zero.pri
#emit lctrl 7
#emit stor.s.pri jit_enabled
format(results_buf, sizeof(results_buf), "JIT: %s", jit_enabled ? ("on") : ("off"));
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
format(results_buf, sizeof(results_buf), "Total PVars: %d", NUM_PVARS);
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
format(results_buf, sizeof(results_buf), "Pawn variable get: %d", t1);
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
format(results_buf, sizeof(results_buf), "PVar get: %d", t2);
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
format(results_buf, sizeof(results_buf), "Pawn variable set: %d", t3);
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
format(results_buf, sizeof(results_buf), "PVar set: %d", t4);
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
#emit load.pri y
}
Код:
JIT: off
Total PVars: 1
Pawn variable get: 85
PVar get: 4152
Pawn variable set: 91
PVar set: 4100
JIT: on
Total PVars: 1
Pawn variable get: 38
PVar get: 4114
Pawn variable set: 47
PVar set: 4077
JIT: off
Total PVars: 20
Pawn variable get: 95
PVar get: 4427
Pawn variable set: 73
PVar set: 4353
JIT: off
Total PVars: 100
Pawn variable get: 89
PVar get: 5360
Pawn variable set: 86
PVar set: 5487
В сравнении с тестом DeimoS'а разница куда большая. Возможно это из-за того, что в первом образце кода нет создания переменной в цикле. (Как можно было вообще додуматься так насиловать стек? Конечно, тогда обычная переменная будет "откликаться" медленнее.)
Ещё один вариант: в предыдущем тесте для каждого отрывка используется цикл на миллион итераций. Скорее всего процессор просто помещает нужные блоки памяти из секций данных и кода в процессорный кэш, что и влияет на производительности. В реальных ситуациях такое вряд ли возможно.
В моём же тесте используются вложенные циклы: 1-го уровня на 10 000 итераций и второго на 100. В результате получается тот же миллион итераций, но без побочных эффектов с кэшированием. Но про кэширование это лишь моя догадка.
При включении JIT повышается быстродействие обычных переменных (что в принципе логично, JIT повышает производительность кода на Pawn, а не нативных функций).
При увеличении кол-ва активных PVar'ов наоборот увеличивается время их отклика. На самом деле, для самого первого PVar'а время остаётся таким же, а для последующих оно увеличивается пропорционально с увеличением внутреннего ID.
Иными словами, чем позднее создан PVar, тем больше время его отклика. Это происходит из-за того, что сервер совершает линейный поиск по всем слотам для PVar'ов в поисках слота с нужным именем.
И да, если кто-то назовёт меня теоретиком, аргументируя, что в реальных проектах не используется так много PVar'ов - посмотрите сначала на исходники какого-нибудь крупного проекта (например, WCRP - там по какой-то странной причине PVar'ы используются практически для всего).
Btw, упаковав массив, можно использовать вчетверо меньше памяти, при этом практически не жертвуя скоростью в сравнении с PVar. Что собственно и сделал автор темы.
Сообщение от
ziggi
Видимо что-то изменилось, по крайней мере так было раньше:
- "In Visual C++4.2, the Standard C++ header files contained a typedef that equated bool with int. In Visual C++ 5.0 and later, bool is implemented as a built-in type with a size of 1 byte. That means that for Visual C++ 4.2, a call of sizeof(bool) yields 4, while in Visual C++ 5.0 and later, the same call yields 1" -
источник
- "В памяти компьютера значения констант и переменных типа bool занимают 4 байта." -
источник
Да, размер bool зависит от реализации (т.е. от компилятора или стандартной библиотеки)... как и всё остальное в C++ -__-
Сообщение от
ziggi
- "Учтите, что тип BOOL в C имеет размер 4 байта (= sizeof(int)), а тип Boolean состоит только из одного." -
источник
Так это ж кастомный тип, который специфичен только для функций WIN32 API.
Сообщение от
ziggi
По рукам ходят.
В любом случае, исходники из Open SA-MP явно основаны на слитых исходниках от куя. Об этом можно судить, например, по наличии файлов с расширением ".cpp.orig" в дополнение к файлам с тем же именем, но расширением ".cpp" (например, "func_amx.cpp" и "func_amx.cpp.orig").
Также в исходниках Pawn AMX присутствуют все модификации, которые были сделаны в рамках SA-MP: например, куй отключил опкоды "jump.pri" и "call.pri" (сделано из соображений "безопасности", если верить комментариям в коде).
И да, в тех же исходниках Pawn AMX можно найти дату изменения (видимо, в SA-MP Team тоже пользовались утилитой svnrev, которой пользовался и разработчик Pawn):
А вот что можно найти в amx.c: https://github.com/Sasuke78200/open-...mx/amx.c#L2096
PHP код:
op_call_pri:
// Kye SA-MP Team 9/9/2009 Unsecure opcode
//PUSH((unsigned char *)cip-code);
//cip=(cell *)(code+(int)pri);
//NEXT(cip);
assert(0);
ABORT(amx,AMX_ERR_INVINSTR);
"9/9/2009" - это позднее выхода 0.2x (20.11.2008) и раньше даты релиза 0.3a (19.10.2009), т.е. исходники либо от одной из предрелизных версий 0.3, либо от релиза 0.3a или более поздних версий.
Как раз в одной из ревизий 0.3a добавили PVar'ы, так что в исходниках Open SA-MP они вряд ли являются результатом обратной разработки.