PDA

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



Димарио
17.07.2019, 22:56
Что лучше использовать, переменную привязанную к айди игрока или пвары? Что быстрее?
В каких случаях применять одно, а в каких другое?

Nexius_Tailer
18.07.2019, 15:05
Быстрее переменные, но пвары можно задать в моде, а получить из фильтрскрипта (т.е. данные можно между скриптами в них хранить). Переменные очевидно лучше использовать в любых часто вызываемых событиях, да и в большинстве случаев в принципе, а пвары же либо в случае синхронизации данных между скриптами, либо где-то, где от их скорости мало что зависит, если при этом тебе их использовать удобнее (какие-нибудь промежуточные данные между ответами на многоэтапные диалоги запоминать, ну или что-нибудь в таком роде).

А, ну и у пваров есть лимит (насколько помню, в 800), хотя его при их использовании по назначению вряд ли достичь можно.

Пельмень
01.08.2019, 18:59
Дарю тебе переписанные пвары, скомпиль в плагин и юзай без лимитов и потери скорости



#include "pvar.h"

int CPlayerVar::FindVarID(char* varName)
{
auto it = std::find_if(std::begin(pVars), std::end(pVars), [&](PVAR_DATA &var) { return varName == var.pVarName; });
if (it != pVars.end())
{
return std::distance(pVars.begin(), it);
}
return -1;
}

int CPlayerVar::SetIntVar(char* varName, int varValue)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_INT)
return 0;

pVars[id].intValue = varValue;
}
else
{
PVAR_DATA var;
var.pVarName = varName;
var.pVarType = PVAR_TYPE_INT;
var.intValue = varValue;
pVars.push_back(var);
}
return 1;
}

int CPlayerVar::SetStringVar(char* varName, char* varString)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_STRING)
return 0;

pVars[id].stringValue = varString;
}
else
{
PVAR_DATA var;
var.pVarName = varName;
var.pVarType = PVAR_TYPE_STRING;
var.stringValue = varString;
pVars.push_back(var);
}
return 1;
}

int CPlayerVar::SetFloatVar(char* varName, float varValue)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_FLOAT)
return 0;

pVars[id].floatValue = varValue;
}
else
{
PVAR_DATA var;
var.pVarName = varName;
var.pVarType = PVAR_TYPE_FLOAT;
var.floatValue = varValue;
pVars.push_back(var);
}
return 1;
}

int CPlayerVar::GetIntVar(char* varName)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_INT)
return 0;

return pVars[id].intValue;
}
return 0;
}

char* CPlayerVar::GetStringVar(char* varName)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_STRING)
return 0;

return &pVars[id].stringValue[0];
}
return 0;
}

float CPlayerVar::GetFloatVar(char* varName)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_FLOAT)
return 0;

return pVars[id].floatValue;
}
return 0;
}

int CPlayerVar::DeleteVar(char* varName)
{
const int id = FindVarID(varName);
if (id != -1)
{
pVars.erase(std::remove_if(pVars.begin(), pVars.end(), [&](const PVAR_DATA& e) { return varName == e.pVarName; }), pVars.end());
return 1;
}
return 0;
}

int CPlayerVar::GetVarType(char* varName)
{
const int id = FindVarID(varName);
if (id != -1)
{
return pVars[id].pVarType;
}
return PVAR_TYPE_NONE;
}




#ifndef __CPVAR_H__
#define __CPVAR_H__

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>

enum PVAR_TYPE
{
PVAR_TYPE_NONE,
PVAR_TYPE_INT,
PVAR_TYPE_STRING,
PVAR_TYPE_FLOAT
};

typedef struct PVAR_DATA_t
{
std::string pVarName;
PVAR_TYPE pVarType;
int intValue;
float floatValue;
std::string stringValue;
} PVAR_DATA;

class CPlayerVar
{
public:
std::vector<PVAR_DATA> pVars;

int DeleteVar(char* varName);

int SetIntVar(char* varName, int varValue);
int SetStringVar(char* varName, char* varString);
int SetFloatVar(char* varName, float varValue);

int GetIntVar(char* varName);
char* GetStringVar(char* varName);
float GetFloatVar(char* varName);
int GetVarType(char* varName);
int FindVarID(char* varName);
};

#endif


Не помню тесты, но если не ошибаюсь +- что и переменные, не знаю какой тут онлайн на форуме, но если нужно кому-то кроме тебя, переделаю в SIMD

Nexius_Tailer
01.08.2019, 19:04
Дарю тебе переписанные пвары, скомпиль в плагин и юзай без лимитов и потери скорости



#include "pvar.h"

int CPlayerVar::FindVarID(char* varName)
{
auto it = std::find_if(std::begin(pVars), std::end(pVars), [&](PVAR_DATA &var) { return varName == var.pVarName; });
if (it != pVars.end())
{
return std::distance(pVars.begin(), it);
}
return -1;
}

int CPlayerVar::SetIntVar(char* varName, int varValue)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_INT)
return 0;

pVars[id].intValue = varValue;
}
else
{
PVAR_DATA var;
var.pVarName = varName;
var.pVarType = PVAR_TYPE_INT;
var.intValue = varValue;
pVars.push_back(var);
}
return 1;
}

int CPlayerVar::SetStringVar(char* varName, char* varString)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_STRING)
return 0;

pVars[id].stringValue = varString;
}
else
{
PVAR_DATA var;
var.pVarName = varName;
var.pVarType = PVAR_TYPE_STRING;
var.stringValue = varString;
pVars.push_back(var);
}
return 1;
}

int CPlayerVar::SetFloatVar(char* varName, float varValue)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_FLOAT)
return 0;

pVars[id].floatValue = varValue;
}
else
{
PVAR_DATA var;
var.pVarName = varName;
var.pVarType = PVAR_TYPE_FLOAT;
var.floatValue = varValue;
pVars.push_back(var);
}
return 1;
}

int CPlayerVar::GetIntVar(char* varName)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_INT)
return 0;

return pVars[id].intValue;
}
return 0;
}

char* CPlayerVar::GetStringVar(char* varName)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_STRING)
return 0;

return &pVars[id].stringValue[0];
}
return 0;
}

float CPlayerVar::GetFloatVar(char* varName)
{
const int id = FindVarID(varName);
if (id != -1)
{
if (pVars[id].pVarType != PVAR_TYPE_FLOAT)
return 0;

return pVars[id].floatValue;
}
return 0;
}

int CPlayerVar::DeleteVar(char* varName)
{
const int id = FindVarID(varName);
if (id != -1)
{
pVars.erase(std::remove_if(pVars.begin(), pVars.end(), [&](const PVAR_DATA& e) { return varName == e.pVarName; }), pVars.end());
return 1;
}
return 0;
}

int CPlayerVar::GetVarType(char* varName)
{
const int id = FindVarID(varName);
if (id != -1)
{
return pVars[id].pVarType;
}
return PVAR_TYPE_NONE;
}




#ifndef __CPVAR_H__
#define __CPVAR_H__

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>

enum PVAR_TYPE
{
PVAR_TYPE_NONE,
PVAR_TYPE_INT,
PVAR_TYPE_STRING,
PVAR_TYPE_FLOAT
};

typedef struct PVAR_DATA_t
{
std::string pVarName;
PVAR_TYPE pVarType;
int intValue;
float floatValue;
std::string stringValue;
} PVAR_DATA;

class CPlayerVar
{
public:
std::vector<PVAR_DATA> pVars;

int DeleteVar(char* varName);

int SetIntVar(char* varName, int varValue);
int SetStringVar(char* varName, char* varString);
int SetFloatVar(char* varName, float varValue);

int GetIntVar(char* varName);
char* GetStringVar(char* varName);
float GetFloatVar(char* varName);
int GetVarType(char* varName);
int FindVarID(char* varName);
};

#endif


Не помню тесты, но если не ошибаюсь +- что и переменные, не знаю какой тут онлайн на форуме, но если нужно кому-то кроме тебя, переделаю в SIMD
По скорости в любом случае проигрывать должно.

Пельмень
01.08.2019, 19:08
По скорости в любом случае проигрывать должно.

Проверь, заодно напишешь разницу. В любом случае я не понимаю смысла гнаться за скоростью и вашими "тестами" в 10000000 итераций, чтобы помериться "хто быстрее". Ты никогда не будешь использовать в таком количестве операции (никакие) хотя-бы потому-что лимит твой будет максимум в 1к игроков (и то вряд-ли) захотят сделать что-то одновременно.
Ну а код кенгурушника (Kye) можно и привести в нормальный вид, захочешь еще скорости - можешь в моем коде изменить названия пваров из строк в хэш.

Nexius_Tailer
01.08.2019, 19:13
Проверь, заодно напишешь разницу. В любом случае я не понимаю смысла гнаться за скоростью и вашими "тестами" в 10000000 итераций, чтобы помериться "хто быстрее". Ты никогда не будешь использовать в таком количестве операции (никакие) хотя-бы потому-что лимит твой будет максимум в 1к игроков (и то вряд-ли) захотят сделать что-то одновременно
Ты это выложил, потому как от автора сего логичнее было бы их видеть от тебя, в любом случае мне пока лень.
Касаемо скорости - OnPlayerUpdate вызывается при любом типе синхронизации несколько десятков раз в секунду, потому при использовании в таких и подобных местах игрокам ничего не нужно делать одновременно - достаточно просто синхронизироваться с сервером. А вот теперь и умножь эти десятки вызовов в секунду на максимальное количество игроков, и цифры уже будут более значительными. Если сразу возникает логичный аргумент - нафига их юзать в OnPlayerUpdate - значит это и нужно уточнять как с обычными пварами, чтобы люди в таких местах их как раз не юзали из-за проигрывания в производительности хотя бы на некоторые проценты.

Пельмень
01.08.2019, 19:20
Ты это выложил, потому как от автора сего логичнее было бы их видеть от тебя, в любом случае мне пока лень.
Касаемо скорости - OnPlayerUpdate вызывается при любом типе синхронизации несколько десятков раз в секунду, потому при использовании в таких и подобных местах игрокам ничего не нужно делать одновременно - достаточно просто синхронизироваться с сервером. А вот теперь и умножь эти десятки вызовов в секунду на максимальное количество игроков, и цифры уже будут более значительными. Если сразу возникает логичный аргумент - нафига их юзать в OnPlayerUpdate - значит это и нужно уточнять как с обычными пварами, чтобы люди в таких местах их как раз не юзали из-за проигрывания в производительности хотя бы на некоторые проценты.

Мне не нужны замеры скорости, пойми, я на форуме 1 раз в год, чтобы ты понимал, свомп не умеет асинхрон, поэтому все операции идут друг за другом, значит больше чем 1 операцию в такт ты не сможешь

Nexius_Tailer
01.08.2019, 19:23
Мне не нужны замеры скорости, пойми, я на форуме 1 раз в год, чтобы ты понимал, свомп не умеет асинхрон, поэтому все операции идут друг за другом, значит больше чем 1 операцию в такт ты не сможешь
И как это связано с тем, что что-то одно быстрее, а что-то другое медленнее? Ты утверждаешь, что у них нет потери скорости, и как минимум это очень спорно и требует подтверждения тестами от тебя же.

Пельмень
01.08.2019, 19:27
И как это связано с тем, что что-то одно быстрее, а что-то другое медленнее? Ты утверждаешь, что у них нет потери скорости, и как минимум это очень спорно и требует подтверждения тестами от тебя же.

Я не буду делать тесты, я забил на свомп еще когда ты экзамены в школе сдавал, если тебе нужны замеры - делай, не хочешь - не используй, просто я знаю свой код, и свомповский высер пваров далёк от моего кода, хочешь сделать лучше, сделай, можешь даже мой код выложить как за свой, я не расстроюсь

Nexius_Tailer
01.08.2019, 19:30
Я не буду делать тесты, я забил на свомп еще когда ты экзамены в школе сдавал, если тебе нужны замеры - делай, не хочешь - не используй, просто я знаю свой код, и свомповский высер пваров далёк от моего кода, хочешь сделать лучше, сделай, можешь даже мой код выложить как за свой, я не расстроюсь
Довольно забавные формулировки, такими обычно и пишут те, кому ещё в школе экзамены сдавать. Насчёт тестов - я уже откажусь от этого чисто из принципов, потому что первым про производительность написал ты, и при этом как автор того, что якобы "не теряет в скорости", ты это ничем подкреплять не решаешься.

Daniel_Cortez
04.08.2019, 13:51
если нужно кому-то кроме тебя, переделаю в SIMD
Это такая шутка, да?

x86
05.08.2019, 03:28
Это такая шутка, да?

Что тут такого... человек любит платформо-зависимые реализации. Вероятно он хотел сделать что-то вроде унроллинга (сразу проверять несколько байт) для функции поиска по строке.

Daniel_Cortez
06.08.2019, 20:10
Что тут такого... человек любит платформо-зависимые реализации. Вероятно он хотел сделать что-то вроде унроллинга (сразу проверять несколько байт) для функции поиска по строке.
Для манипуляций со строками есть функции из стандартной библиотеки, которые как раз и могут быть реализованы с использованием SIMD (как, например, в glibc или библиотеках MSVC++). В остальном для PVar'ов векторные инструкции - как собаке пятая нога, а потому и предложение добавить SIMD в PVar'ы выглядит как либо незнание сферы применения, либо просто неумелый троллинг.

x86
06.08.2019, 23:45
Для манипуляций со строками есть функции из стандартной библиотеки, которые как раз и могут быть реализованы с использованием SIMD (как, например, в glibc или библиотеках MSVC++). В остальном для PVar'ов векторные инструкции - как собаке пятая нога, а потому и предложение добавить SIMD в PVar'ы выглядит как либо незнание сферы применения, либо просто неумелый троллинг.

Векторные инструкции применяют во многих сферах. В том числе и имплементации поисковых функций. А вообще вот тут проводили тесты https://gms.tf/stdfind-and-memchr-optimizations.html

Daniel_Cortez
08.08.2019, 18:18
Векторные инструкции применяют во многих сферах. В том числе и имплементации поисковых функций. А вообще вот тут проводили тесты https://gms.tf/stdfind-and-memchr-optimizations.html
Это всё те же стандартные строковые/цепочечные функции, про которые я уже ответил в посте выше.