PDA

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



BossArturKA
13.10.2015, 03:56
Всем привет. Дело было вечером, делать было нечего.
Написал простенький скрипт, для сравнения скорости.
Массив же быстрее PVar? На кой фиг его (PVar) тогда вообще использовать?
Не раз натыкался на рекомендации, использовать PVar вместо массива, якобы быстрее работает.
http://i.imgur.com/gxcFE4o.png
Цикл первый - массив. Цикл второй - PVar.


#include <a_samp>
main() return true;
new pertest[MAX_PLAYERS], allinfo[3][2], allvs;
public OnGameModeInit() return vs();
stock vs(){
if(allvs > 99) return true;
allvs++;
allinfo[2][0] = GetTickCount();
for(new i1; i1 < 500000; i1++) pertest[0] = 0;
allinfo[1][0] = GetTickCount() - allinfo[2][0], allinfo[2][1] = GetTickCount();
for(new i2 = 0; i2 < 500000; i2 ++) SetPVarInt(0, "i2", 0);
allinfo[1][1] = GetTickCount() - allinfo[2][1];
if(allinfo[1][0] < allinfo[1][1]) printf("Цикл 1 выполнен за %d ms. Цикл 2 выполнен за %d ms | Цикл 1 быстрее %d ms.", allinfo[1][0], allinfo[1][1], allinfo[1][1]-allinfo[1][0]), allinfo[0][0]++;
else if(allinfo[1][0] > allinfo[1][1]) printf("Цикл 1 выполнен за %d ms. Цикл 2 выполнен за %d ms | Цикл 2 быстрее на %d ms.", allinfo[1][0], allinfo[1][1], allinfo[1][0]-allinfo[1][1]), allinfo[0][1]++;
else printf("Цикл 1 выполнен за %d ms. Цикл 2 выполнен за %d ms | Скорость циклов равна.", allinfo[1][0], allinfo[1][1]);
return printf("Score: Цикл 1: %d | Цикл 2: %d.", allinfo[0][0], allinfo[0][1]), vs();
}

Вопрос выделен красным цветом.
Сток вызывает сам себя 100 раз, для теста.

NewGreen
13.10.2015, 10:29
Всем привет. Дело было вечером, делать было нечего.
Написал простенький скрипт, для сравнения скорости.
Массив же быстрее PVar? На кой фиг его (PVar) тогда вообще использовать?
Не раз натыкался на рекомендации, использовать PVar вместо массива, якобы быстрее работает.

В давние времена, когда SAMP был еще "маленький", он был рассчитан на 100 игроков, но прошло время, и SAMP вырос, и уже 500 игроков могли играть одновременно, а потом и 1000.
Еще в SAMP'e была и есть константа MAX_PLAYERS, обозначающая - максимальное количество игроков, сначала она была равна 100, потом 500, и наконец 1000.
Многие "скриптеры", создавали и создают массивы с использованием MAX_PLAYERS, лишь для хранения одиночных флагов (1, 0 и т.п.), когда MAX_PLAYERS была равна 100, это еще было терпимо, но сейчас, подобное использование массивов слишком затратно в плане потребления памяти.

Как нам известно, 1 ячейка массива занимает 4 байта, рассчитаем потребление памяти на один массив:

MAX_PLAYERS при:
100 * 4 занимало памяти 400 байт;
500 * 4 занимало памяти 2000 байт;
1000 * 4 занимает памяти 4000 байт;

А если на сервере играют, к примеру 100 человек, то остальные 900 ячеек массива, возможно, никогда не будут использованы, а это, не задействованные 3600 байт.

В связи с этим, была создана Per-player variable system (сокращенно PVar), система персональных переменых, имеет ряд преимуществ, по сравнению со стандартными переменными:

Доступность из всех загруженных модов и фильтр скриптов, позволяет упростить модуляризацию кода.
Автоматическое удаление PVar'ов, когда игрок выходит с сервера, что позволяет не сбрасывать вручную переменные для следующего подключившегося игрока.
PVar'ы экономят память, не расходуя ее на элементы на не подключенных игроков.
Если даже PVar не был создан, при запросе он по-прежнему будет возвращать значение по умолчанию 0.
PVar'ы могут хранить очень большие строки используя динамически выделяемую память.


К недостаткам, возможно, можно отнести скорость работы, но я считаю, что это не очень критично.

Полное описание PVar можно прочесть тут https://wiki.sa-mp.com/wiki/Per-player_variable_system

BossArturKA
13.10.2015, 10:39
NewGreen, в принципе это цитата с форума са-мп.сом.
Вот интересный пункт,
Если даже PVar не был создан, при запросе он по-прежнему будет возвращать значение по умолчанию 0.Но вот в чем дело, получается он так-же хранит значение 0 (Якобы не создан) для каждого игрока =).

NewGreen
13.10.2015, 10:54
NewGreen, в принципе это цитата с форума са-мп.сом.
Вот интересный пункт, Но вот в чем дело, получается он так-же хранит значение 0 (Якобы не создан) для каждого игрока =).
Возможно, это сделано для защиты, т.к. пусть лучше PVar'ы будут возвращать определенное значение, чем не определенное.
Это можно сравнить с обращением к несуществующей ячейке массива, что приведет к выходу за границы массива, а PVar в этом случае вернет 0.

Daniel_Cortez
13.10.2015, 11:05
Возможно, это сделано для защиты, т.к. пусть лучше PVar'ы будут возвращать определенное значение, чем не определенное.
Это можно сравнить с обращением к несуществующей ячейке массива, что приведет к выходу за границы массива, а PVar в этом случае вернет 0.
Можно было сделать, как в GetPlayerHealth:


new Float: hp;
new result = GetPlayerHealth(playerid, hp);

Здесь в случае, если игрок не подключен, в переменной result будет 0, в случае успешного выполнения - 1.
Точно так же можно было с самого начала сделать в GetPVarInt. Выбор же в пользу неопределённости между 0 и несуществующим значением - не что иное, как показатель некомпетентности разработчика (Kalcor). Впрочем, для него это не первый раз, и далеко не последний.

NewGreen
13.10.2015, 11:21
Можно было сделать, как в GetPlayerHealth:


new Float: hp;
new result = GetPlayerHealth(playerid, hp);

Здесь в случае, если игрок не подключен, в переменной result будет 0, в случае успешного выполнения - 1.
Точно так же можно было с самого начала сделать в GetPVarInt. Выбор же в пользу неопределённости между 0 и несуществующим значением - не что иное, как показатель некомпетентности разработчика (Kalcor). Впрочем, для него это не первый раз, и далеко не последний.
Увы, пока исходный код закрыт, мало что можно сделать.

Daniel_Cortez
13.10.2015, 16:25
Увы, пока исходный код закрыт, мало что можно сделать.
Я и не предлагал ничего менять. Просто хотел сказать, что не нужно оправдывать быдлокодеров предположениями о какой-то мифической защите.
Вывод очевиден: из куя проектировщик абсолютно никакой, ибо у него нет никаких чётких стандартов.

Вот ещё пример: функции TextDrawCreate и CreatePlayerTextDraw - названия составлены совершенно по разному, легко запутаться. В то же время, функции TextDrawDestroy и PlayerTextDrawDestroy названы по одному принципу, что ещё больше вводит в заблуждение. Иногда такое ощущение, будто у куя раздвоение личности или под одним ником скрываются два совершенно разных человека.

BossArturKA
13.10.2015, 16:39
Я и не предлагал ничего менять. Просто хотел сказать, что не нужно оправдывать быдлокодеров предположениями о какой-то мифической защите.
Вывод очевиден: из куя проектировщик абсолютно никакой, ибо у него нет никаких чётких стандартов.

Вот ещё пример: функции TextDrawCreate и CreatePlayerTextDraw - названия составлены совершенно по разному, легко запутаться. В то же время, функции TextDrawDestroy и PlayerTextDrawDestroy названы по одному принципу, что ещё больше вводит в заблуждение. Иногда такое ощущение, будто у куя раздвоение личности или под одним ником скрываются два совершенно разных человека.
Изменить "название" функции сейчас модно :D. Подцепил видимо.