Просмотр полной версии : [Вопрос] Пвары или переменные?
Что лучше использовать, переменную привязанную к айди игрока или пвары? Что быстрее?
В каких случаях применять одно, а в каких другое?
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
Это такая шутка, да?
Это такая шутка, да?
Что тут такого... человек любит платформо-зависимые реализации. Вероятно он хотел сделать что-то вроде унроллинга (сразу проверять несколько байт) для функции поиска по строке.
Daniel_Cortez
06.08.2019, 20:10
Что тут такого... человек любит платформо-зависимые реализации. Вероятно он хотел сделать что-то вроде унроллинга (сразу проверять несколько байт) для функции поиска по строке.
Для манипуляций со строками есть функции из стандартной библиотеки, которые как раз и могут быть реализованы с использованием SIMD (как, например, в glibc или библиотеках MSVC++). В остальном для PVar'ов векторные инструкции - как собаке пятая нога, а потому и предложение добавить SIMD в PVar'ы выглядит как либо незнание сферы применения, либо просто неумелый троллинг.
Для манипуляций со строками есть функции из стандартной библиотеки, которые как раз и могут быть реализованы с использованием 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
Это всё те же стандартные строковые/цепочечные функции, про которые я уже ответил в посте выше.
Powered by vBulletin® Version 4.2.0 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot