Reduce amount of copies for HashedString for improved performance
continuous-integration/drone/push Build is passing Details

Signed-off-by: Deukhoofd <deukhoofd@gmail.com>
This commit is contained in:
Deukhoofd 2019-06-25 15:18:36 +02:00
parent bace7b294d
commit 48224afe45
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
13 changed files with 62 additions and 57 deletions

View File

@ -39,7 +39,7 @@ namespace Porygon::Binder {
_currentScope--;
}
int BoundScope::Exists(Utilities::HashedString key) {
int BoundScope::Exists(const Utilities::HashedString& key) {
auto found = this->_tableScope->find(key);
if (found != _tableScope->end()) {
return 0;
@ -54,7 +54,7 @@ namespace Porygon::Binder {
return -1;
}
BoundVariable *BoundScope::GetVariable(uint32_t scope, Utilities::HashedString identifier) {
BoundVariable *BoundScope::GetVariable(uint32_t scope, const Utilities::HashedString& identifier) {
if (scope == 0) {
auto find = this->_tableScope->find(identifier);
if (find != _tableScope->end()) {
@ -71,7 +71,7 @@ namespace Porygon::Binder {
}
}
VariableAssignment BoundScope::CreateExplicitLocal(Utilities::HashedString identifier, std::shared_ptr<ScriptType> type) {
VariableAssignment BoundScope::CreateExplicitLocal(const Utilities::HashedString& identifier, std::shared_ptr<ScriptType> type) {
auto scope = this->_localScope.at(this->_currentScope - 1);
if (scope->find(identifier) != scope->end()) {
return VariableAssignment(VariableAssignmentResult::ExplicitLocalVariableExists, nullptr);
@ -81,7 +81,7 @@ namespace Porygon::Binder {
new BoundVariableKey(identifier, this->_currentScope, true));
}
VariableAssignment BoundScope::AssignVariable(Utilities::HashedString identifier, const std::shared_ptr<ScriptType> &type) {
VariableAssignment BoundScope::AssignVariable(const Utilities::HashedString& identifier, const std::shared_ptr<ScriptType> &type) {
int exists = this->Exists(identifier);
if (exists == -1) {
// Creation

View File

@ -28,13 +28,13 @@ namespace Porygon::Binder {
void GoOuterScope();
int Exists(Utilities::HashedString key);
int Exists(const Utilities::HashedString& key);
BoundVariable *GetVariable(uint32_t scope, Utilities::HashedString identifier);
BoundVariable *GetVariable(uint32_t scope, const Utilities::HashedString& identifier);
VariableAssignment CreateExplicitLocal(Utilities::HashedString identifier, std::shared_ptr<ScriptType> type);
VariableAssignment CreateExplicitLocal(const Utilities::HashedString& identifier, std::shared_ptr<ScriptType> type);
VariableAssignment AssignVariable(Utilities::HashedString identifier, const std::shared_ptr<ScriptType> &type);
VariableAssignment AssignVariable(const Utilities::HashedString& identifier, const std::shared_ptr<ScriptType> &type);
size_t GetLocalVariableCount() {
return _localScope.size();

View File

@ -40,21 +40,21 @@ namespace Porygon::Evaluation {
const shared_ptr<EvalValue> IndexValue(EvalValue *val) const final {
const auto stringKey = val->EvaluateString();
return this->_table->at(Utilities::HashedString(stringKey));
return this->_table->at(Utilities::HashedString::CreateLookup(stringKey));
}
const shared_ptr<EvalValue> IndexValue(uint32_t hash) const final {
return this->_table->at(Utilities::HashedString(hash));
return this->_table->at(Utilities::HashedString::CreateLookup(hash));
}
const shared_ptr<EvalValue> IndexValue(const char *val) const {
auto hash = Utilities::HashedString::ConstHash(val);
return this->_table->at(Utilities::HashedString(hash));
return this->_table->at(Utilities::HashedString::CreateLookup(hash));
}
void SetIndexValue(EvalValue *key, const shared_ptr<EvalValue> &value) const final {
auto hash = key->GetHashCode();
this->_table->at(Utilities::HashedString(hash)) = value;
this->_table->at(Utilities::HashedString::CreateLookup(hash)) = value;
}
const _Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<EvalValue>>> GetTableIterator() const{

View File

@ -392,7 +392,7 @@ namespace Porygon::Evaluation {
auto values = new map<Utilities::HashedString, shared_ptr<EvalValue>>();
for (int i = 0; i < valueExpressions->size(); i++) {
auto val = this->EvaluateExpression(valueExpressions->at(i));
auto key = Utilities::StringUtils::IntToString(i + 1);
auto key = new u16string(Utilities::StringUtils::IntToString(i + 1));
values->insert({Utilities::HashedString(key), val});
}
auto valuesPointer = shared_ptr<map<Utilities::HashedString, shared_ptr<EvalValue>>>(values);

View File

@ -256,7 +256,7 @@ namespace Porygon::Parser {
case HashedString::ConstHash("while"):
return new SimpleToken(TokenKind::WhileKeyword, start, 5);
default:
return new IdentifierToken(HashedString(s), start, s.length());
return new IdentifierToken(HashedString(new u16string(s)), start, s.length());
}
}

View File

@ -67,11 +67,11 @@ void Porygon::Script::Parse(const u16string& script) {
}
EvalValue *Porygon::Script::GetVariable(const u16string &key) {
return _scriptVariables -> at(HashedString(key)).get();
return _scriptVariables -> at(HashedString::CreateLookup(key)).get();
}
bool Porygon::Script::HasVariable(const u16string &key) {
auto f = _scriptVariables->find(HashedString(key));
auto f = _scriptVariables->find(HashedString::CreateLookup(key));
return f != _scriptVariables->end();
}
@ -80,7 +80,7 @@ EvalValue *Porygon::Script::GetLastValue() {
}
bool Porygon::Script::HasFunction(const u16string &key) {
auto f = _scriptVariables->find(HashedString(key));
auto f = _scriptVariables->find(HashedString::CreateLookup(key));
return f != _scriptVariables->end() && f.operator->()->second->GetTypeClass() == TypeClass ::Function;
}

View File

@ -1,4 +1,3 @@
#include <utility>
#ifndef PORYGONLANG_SCRIPT_HPP
#define PORYGONLANG_SCRIPT_HPP

View File

@ -33,13 +33,13 @@ namespace Porygon{
const shared_ptr<ScriptType> GetIndexedType(ScriptType* indexer) const final{
auto stringKey = (StringScriptType*)indexer;
if (stringKey->IsKnownAtBind()){
return _values-> at(Utilities::HashedString(stringKey->GetHashValue()))->GetType();
return _values-> at(Utilities::HashedString::CreateLookup(stringKey->GetHashValue()))->GetType();
}
throw "TODO: indexing with dynamic keys";
}
const shared_ptr<ScriptType> GetIndexedType(uint32_t hash) const final{
return _values-> at(Utilities::HashedString(hash))->GetType();
return _values-> at(Utilities::HashedString::CreateLookup(hash))->GetType();
}
const map<Utilities::HashedString, BoundVariable*>* GetValues() const{

View File

@ -3,32 +3,33 @@
#define PORYGONLANG_HASHEDSTRING_HPP
#include <string>
#include <memory>
namespace Porygon::Utilities{
class HashedString{
const uint32_t _hash;
const std::u16string _string;
const std::shared_ptr<const std::u16string> _string;
explicit HashedString(const std::u16string& s) : _hash(ConstHash(s.c_str())),_string(nullptr){
}
explicit HashedString(uint32_t hash) : _hash(hash), _string(nullptr){
}
public:
explicit HashedString(const std::u16string& s)
: _hash(ConstHash(s.c_str())),
_string(s)
explicit HashedString(const std::u16string* s)
: _hash(ConstHash(s->c_str())),
_string(std::shared_ptr<const std::u16string>(s))
{
}
explicit HashedString(char16_t const *input)
: _hash(ConstHash(input)),
_string(std::u16string(input))
{
static HashedString CreateLookup(const std::u16string& s){
return HashedString(s);
}
static HashedString CreateLookup(uint32_t hash){
return HashedString(hash);
}
explicit HashedString(char const *input) : _hash(ConstHash(input)){
}
explicit HashedString(uint32_t hash) : _hash(hash){
}
HashedString(const HashedString& b) :_hash(b._hash), _string(b._string){
};
HashedString(const HashedString& b) = default;
static uint32_t constexpr ConstHash(char16_t const *input) {
return *input ?
@ -46,8 +47,8 @@ namespace Porygon::Utilities{
return _hash;
}
const std::u16string* GetString() const{
return &_string;
const std::shared_ptr<const std::u16string> GetString() const{
return _string;
}
bool operator==(const HashedString& b) const{

View File

@ -0,0 +1,5 @@
#include "StringUtils.hpp"
namespace Porygon::Utilities{
std::wstring_convert<std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::little_endian>, char16_t> StringUtils::conv;
}

View File

@ -10,9 +10,9 @@
namespace Porygon::Utilities{
class StringUtils{
static std::wstring_convert<std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::little_endian>, char16_t> conv;
public:
static std::u16string IntToString(long const &i) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::little_endian>, char16_t> conv;
return conv.from_bytes(std::to_string(i));
}
};

View File

@ -349,7 +349,7 @@ TEST_CASE( "Lex identifier", "[lexer]" ) {
REQUIRE(tokens.size() == 2);
const IToken* firstToken = tokens[0];
REQUIRE(firstToken -> GetKind() == TokenKind::Identifier);
REQUIRE(((IdentifierToken*)firstToken) -> GetValue() == HashedString("foo"));
REQUIRE(((IdentifierToken*)firstToken) -> GetValue() == HashedString::CreateLookup(u"foo"));
for (auto t: tokens){
delete t;
}

View File

@ -203,7 +203,7 @@ TEST_CASE( "Parse String Tokens", "[parser]" ) {
TEST_CASE( "Parse Global Assignment", "[parser]" ) {
vector<const IToken*> v {
new IdentifierToken(HashedString("foo"),0,0),
new IdentifierToken(HashedString::CreateLookup(u"foo"),0,0),
new SimpleToken(TokenKind::AssignmentToken,0,0),
new SimpleToken(TokenKind::TrueKeyword,0,0),
new SimpleToken(TokenKind::EndOfFile,0,0)
@ -216,7 +216,7 @@ TEST_CASE( "Parse Global Assignment", "[parser]" ) {
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Assignment);
auto assignment = (ParsedAssignmentStatement*)firstStatement;
REQUIRE(!assignment -> IsLocal());
REQUIRE(assignment->GetIdentifier().GetHash() == HashedString("foo").GetHash());
REQUIRE(assignment->GetIdentifier().GetHash() == HashedString::CreateLookup(u"foo").GetHash());
REQUIRE(((LiteralBoolExpression*)assignment->GetExpression()) -> GetValue());
for (auto t : v){
@ -228,7 +228,7 @@ TEST_CASE( "Parse Global Assignment", "[parser]" ) {
TEST_CASE( "Parse local Assignment", "[parser]" ) {
vector<const IToken*> v {
new SimpleToken(TokenKind::LocalKeyword,0,0),
new IdentifierToken(HashedString("foo"),0,0),
new IdentifierToken(HashedString(new u16string(u"foo")),0,0),
new SimpleToken(TokenKind::AssignmentToken,0,0),
new SimpleToken(TokenKind::TrueKeyword,0,0),
new SimpleToken(TokenKind::EndOfFile,0,0)
@ -241,7 +241,7 @@ TEST_CASE( "Parse local Assignment", "[parser]" ) {
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Assignment);
auto assignment = (ParsedAssignmentStatement*)firstStatement;
REQUIRE(assignment -> IsLocal());
REQUIRE(assignment->GetIdentifier().GetHash() == HashedString("foo").GetHash());
REQUIRE(assignment->GetIdentifier().GetHash() == HashedString::CreateLookup(u"foo").GetHash());
REQUIRE(((LiteralBoolExpression*)assignment->GetExpression()) -> GetValue());
for (auto t : v){
@ -254,17 +254,17 @@ TEST_CASE( "Parse local Assignment", "[parser]" ) {
TEST_CASE( "Parse function declaration", "[parser]" ){
vector<const IToken*> v {
new SimpleToken(TokenKind::FunctionKeyword,0,0),
new IdentifierToken(HashedString("foo"),0,0),
new IdentifierToken(HashedString(new u16string(u"foo")),0,0),
new SimpleToken(TokenKind::OpenParenthesis,0,0),
new IdentifierToken(HashedString("number"),0,0),
new IdentifierToken(HashedString("bar"),0,0),
new IdentifierToken(HashedString(new u16string(u"number")),0,0),
new IdentifierToken(HashedString(new u16string(u"bar")),0,0),
new SimpleToken(TokenKind::CommaToken,0,0),
new IdentifierToken(HashedString("number"),0,0),
new IdentifierToken(HashedString("par"),0,0),
new IdentifierToken(HashedString(new u16string(u"number")),0,0),
new IdentifierToken(HashedString(new u16string(u"par")),0,0),
new SimpleToken(TokenKind::CloseParenthesis,0,0),
new IdentifierToken(HashedString("bar"),0,0),
new IdentifierToken(HashedString(new u16string(u"bar")),0,0),
new SimpleToken(TokenKind::PlusToken,0,0),
new IdentifierToken(HashedString("par"),0,0),
new IdentifierToken(HashedString(new u16string(u"par")),0,0),
new SimpleToken(TokenKind::EndKeyword,0,0),
new SimpleToken(TokenKind::EndOfFile,0,0),
};
@ -275,12 +275,12 @@ TEST_CASE( "Parse function declaration", "[parser]" ){
auto firstStatement = parsedStatements -> at(0);
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::FunctionDeclaration);
auto functionDeclaration = (ParsedFunctionDeclarationStatement*)firstStatement;
REQUIRE(functionDeclaration->GetIdentifier() == HashedString("foo"));
REQUIRE(functionDeclaration->GetIdentifier() == HashedString::CreateLookup(u"foo"));
auto parameters = functionDeclaration->GetParameters();
CHECK(parameters -> at(0) ->GetType() == HashedString("number"));
CHECK(parameters -> at(0) ->GetIdentifier() == HashedString("bar"));
CHECK(parameters -> at(1) ->GetType() == HashedString("number"));
CHECK(parameters -> at(1) ->GetIdentifier() == HashedString("par"));
CHECK(parameters -> at(0) ->GetType() == HashedString::CreateLookup(u"number"));
CHECK(parameters -> at(0) ->GetIdentifier() == HashedString::CreateLookup(u"bar"));
CHECK(parameters -> at(1) ->GetType() == HashedString::CreateLookup(u"number"));
CHECK(parameters -> at(1) ->GetIdentifier() == HashedString::CreateLookup(u"par"));
for (auto t : v){
delete t;