Skip calling has_property() before get_property()

Instead just do the normal Javascript thing of checking if we got `undefined`.
This nearly doubles the speed of value_for_property() as nearly all of the time
was spent in looking up the properties in the JS object.
This commit is contained in:
Thomas Goyne 2018-06-20 12:40:22 -07:00
parent 5d182a6bf3
commit 55fe200446
4 changed files with 5 additions and 26 deletions

View File

@ -68,10 +68,10 @@ public:
OptionalValue value_for_property(ValueType dict, std::string const& prop_name, size_t prop_index) { OptionalValue value_for_property(ValueType dict, std::string const& prop_name, size_t prop_index) {
ObjectType object = Value::validated_to_object(m_ctx, dict); ObjectType object = Value::validated_to_object(m_ctx, dict);
if (!Object::has_property(m_ctx, object, prop_name)) { ValueType value = Object::get_property(m_ctx, object, prop_name);
if (Value::is_undefined(m_ctx, value)) {
return util::none; return util::none;
} }
ValueType value = Object::get_property(m_ctx, object, prop_name);
const auto& prop = m_object_schema->persisted_properties[prop_index]; const auto& prop = m_object_schema->persisted_properties[prop_index];
if (!Value::is_valid_for_property(m_ctx, value, prop)) { if (!Value::is_valid_for_property(m_ctx, value, prop)) {
throw TypeErrorException(*this, m_object_schema->name, prop, value); throw TypeErrorException(*this, m_object_schema->name, prop, value);

View File

@ -210,8 +210,6 @@ struct Object {
static ValueType get_prototype(ContextType, const ObjectType &); static ValueType get_prototype(ContextType, const ObjectType &);
static void set_prototype(ContextType, const ObjectType &, const ValueType &); static void set_prototype(ContextType, const ObjectType &, const ValueType &);
static bool has_property(ContextType, const ObjectType &, const String<T> &);
static bool has_property(ContextType, const ObjectType &, uint32_t);
static ValueType get_property(ContextType, const ObjectType &, const String<T> &); static ValueType get_property(ContextType, const ObjectType &, const String<T> &);
static ValueType get_property(ContextType, const ObjectType &, uint32_t); static ValueType get_property(ContextType, const ObjectType &, uint32_t);
static void set_property(ContextType, const ObjectType &, const String<T> &, const ValueType &, PropertyAttributes attributes = None); static void set_property(ContextType, const ObjectType &, const String<T> &, const ValueType &, PropertyAttributes attributes = None);
@ -223,10 +221,11 @@ struct Object {
template<typename P> template<typename P>
static ValueType validated_get_property(ContextType ctx, const ObjectType &object, const P &property, const char *message = nullptr) { static ValueType validated_get_property(ContextType ctx, const ObjectType &object, const P &property, const char *message = nullptr) {
if (!has_property(ctx, object, property)) { auto value = get_property(ctx, object, property);
if (Value<T>::is_undefined(ctx, value)) {
throw std::out_of_range(message ? message : "Object missing expected property: " + util::to_string(property)); throw std::out_of_range(message ? message : "Object missing expected property: " + util::to_string(property));
} }
return get_property(ctx, object, property); return value;
} }
static uint32_t validated_get_length(ContextType ctx, const ObjectType &object) { static uint32_t validated_get_length(ContextType ctx, const ObjectType &object) {

View File

@ -23,16 +23,6 @@
namespace realm { namespace realm {
namespace js { namespace js {
template<>
inline bool jsc::Object::has_property(JSContextRef ctx, const JSObjectRef &object, const jsc::String &key) {
return JSObjectHasProperty(ctx, object, key);
}
template<>
inline bool jsc::Object::has_property(JSContextRef ctx, const JSObjectRef &object, uint32_t index) {
return JSObjectHasProperty(ctx, object, jsc::String(util::to_string(index)));
}
template<> template<>
inline JSValueRef jsc::Object::get_property(JSContextRef ctx, const JSObjectRef &object, const jsc::String &key) { inline JSValueRef jsc::Object::get_property(JSContextRef ctx, const JSObjectRef &object, const jsc::String &key) {
JSValueRef exception = nullptr; JSValueRef exception = nullptr;

View File

@ -23,16 +23,6 @@
namespace realm { namespace realm {
namespace js { namespace js {
template<>
inline bool node::Object::has_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, const node::String &key) {
return Nan::Has(object, key).FromMaybe(false);
}
template<>
inline bool node::Object::has_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, uint32_t index) {
return Nan::Has(object, index).FromMaybe(false);
}
template<> template<>
inline v8::Local<v8::Value> node::Object::get_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, const node::String &key) { inline v8::Local<v8::Value> node::Object::get_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, const node::String &key) {
Nan::TryCatch trycatch; Nan::TryCatch trycatch;