Avoid unnecessary dictionary lookups

fixes #8922
This commit is contained in:
Gunnar Beutner 2015-03-31 11:45:38 +02:00
parent 43f709c22a
commit 91da55872d
4 changed files with 32 additions and 6 deletions

View File

@ -46,6 +46,27 @@ Value Dictionary::Get(const String& key) const
return it->second; return it->second;
} }
/**
* Retrieves a value from a dictionary.
*
* @param key The key whose value should be retrieved.
* @param result The value of the dictionary item (only set when the key exists)
* @returns true if the key exists, false otherwise.
*/
bool Dictionary::Get(const String& key, Value *result) const
{
ASSERT(!OwnsLock());
ObjectLock olock(this);
std::map<String, Value>::const_iterator it = m_Data.find(key);
if (it == m_Data.end())
return false;
*result = it->second;
return true;
}
/** /**
* Sets a value in the dictionary. * Sets a value in the dictionary.
* *

View File

@ -56,6 +56,7 @@ public:
{ } { }
Value Get(const String& key) const; Value Get(const String& key) const;
bool Get(const String& key, Value *result) const;
void Set(const String& key, const Value& value); void Set(const String& key, const Value& value);
bool Contains(const String& key) const; bool Contains(const String& key) const;

View File

@ -92,8 +92,10 @@ const DebugInfo& DebuggableExpression::GetDebugInfo(void) const
ExpressionResult VariableExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const ExpressionResult VariableExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
{ {
if (frame.Locals && frame.Locals->Contains(m_Variable)) Value value;
return frame.Locals->Get(m_Variable);
if (frame.Locals && frame.Locals->Get(m_Variable, &value))
return value;
else if (frame.Self.IsObject() && frame.Locals != static_cast<Object::Ptr>(frame.Self) && VMOps::HasField(frame.Self, m_Variable)) else if (frame.Self.IsObject() && frame.Locals != static_cast<Object::Ptr>(frame.Self) && VMOps::HasField(frame.Self, m_Variable))
return VMOps::GetField(frame.Self, m_Variable, m_DebugInfo); return VMOps::GetField(frame.Self, m_Variable, m_DebugInfo);
else else

View File

@ -46,8 +46,9 @@ class VMOps
public: public:
static inline Value Variable(ScriptFrame& frame, const String& name, const DebugInfo& debugInfo = DebugInfo()) static inline Value Variable(ScriptFrame& frame, const String& name, const DebugInfo& debugInfo = DebugInfo())
{ {
if (frame.Locals && frame.Locals->Contains(name)) Value value;
return frame.Locals->Get(name); if (frame.Locals && frame.Locals->Get(name, &value))
return value;
else if (frame.Self.IsObject() && frame.Locals != static_cast<Object::Ptr>(frame.Self) && HasField(frame.Self, name)) else if (frame.Self.IsObject() && frame.Locals != static_cast<Object::Ptr>(frame.Self) && HasField(frame.Self, name))
return GetField(frame.Self, name, debugInfo); return GetField(frame.Self, name, debugInfo);
else else
@ -244,8 +245,9 @@ public:
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(object); Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(object);
if (dict) { if (dict) {
if (dict->Contains(field)) Value value;
return dict->Get(field); if (dict->Get(field, &value))
return value;
else else
return GetPrototypeField(context, field, false, debugInfo); return GetPrototypeField(context, field, false, debugInfo);
} }