function getPropertyDescriptor(obj, property) {
const descriptor = Object.getOwnPropertyDescriptor(obj, property);
if (descriptor !== undefined)
return descriptor;
const proto = Object.getPrototypeOf(obj);
if (proto === null)
return undefined;
return getPropertyDescriptor(proto, property);
}
function getPropertyOrDefault(obj, property, defaultValue) {
const d = getPropertyDescriptor(obj, property);
if (d) {
if (Object.prototype.hasOwnProperty.call(d, "value"))
return d.value;
if (Object.prototype.hasOwnProperty.call(d, "get"))
return d.get.call(obj);
}
return defaultValue;
}
function getPropertyOrDefault2(obj, property, defaultValue) {
if (Reflect.has(obj, property)) return obj[property];
return defaultValue;
}
class T {
constructor() {
this.requiredField = 1;
this.undefinableField = undefined;
this.m_requiredProp = 1;
this.m_undefinableProp = undefined;
}
get requiredProp() {
return this.m_requiredProp;
}
set requiredProp(value) {
this.m_requiredProp = value;
}
get undefinableProp() {
return this.m_undefinableProp;
}
set undefinableProp(value) {
this.m_undefinableProp = value;
}
}
var t = new T();
t.requiredField = 1;
t.requiredProp = 1;
class D extends T {}
var d = new D();
d.requiredField = 1;
d.requiredProp = 1;
const v = t.requiredProp;
const v = getPropertyOrDefault(t, "requiredProp", 0);
const v = d.requiredProp
const v = getPropertyOrDefault(d, "requiredProp", 0);
const v = t.requiredField
const v = getPropertyOrDefault(t, "requiredField", 0);
const v = d.requiredField
const v = getPropertyOrDefault(d, "requiredField", 0);
const v = getPropertyOrDefault2(d, "requiredField", 0);
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
requiredProp | |
requiredProp_getPropertyOrDefault | |
derived_requiredProp | |
derived_requiredProp_getPropertyOrDefault | |
requiredField | |
requiredField_getPropertyOrDefault | |
derived_requiredField | |
derived_requiredField_getPropertyOrDefault | |
derived_prop_reflectHas |
Test name | Executions per second |
---|---|
requiredProp | 7844539.0 Ops/sec |
requiredProp_getPropertyOrDefault | 391684.3 Ops/sec |
derived_requiredProp | 7662199.5 Ops/sec |
derived_requiredProp_getPropertyOrDefault | 294174.0 Ops/sec |
requiredField | 7638949.0 Ops/sec |
requiredField_getPropertyOrDefault | 778359.7 Ops/sec |
derived_requiredField | 7745280.0 Ops/sec |
derived_requiredField_getPropertyOrDefault | 782821.4 Ops/sec |
derived_prop_reflectHas | 2008201.8 Ops/sec |
Measuring the performance of different approaches to accessing properties in JavaScript can be interesting.
Benchmark Definition
The provided JSON represents a benchmark definition, which outlines the test cases and their respective scripts. The main script consists of several objects with requiredProp
, derived_requiredField
, and derived_requiredProp
methods. These methods attempt to access properties on an object using different approaches.
requiredProp
: Directly accesses a property using its name.derived_requiredField
: Uses the in
operator to check if a property exists, followed by accessing it using its name.derived_requiredProp
: Uses the in
operator to check if a property exists, and then uses the hasOwnProperty
method to access it.Test Cases
The test cases are run repeatedly on different browsers (Chrome 94) with varying execution rates per second. The results show which approach is faster for each test case.
Analysis
Based on the provided data, here's a brief analysis of the performance differences:
requiredProp
and derived_requiredField
have similar performance, with requiredProp
being slightly faster.derived_requiredProp
is slower than both requiredProp
and derived_requiredField
.requiredProp
and derived_requiredField
is relatively small, around 5-10%.derived_requiredProp
performs worse due to the additional overhead of calling hasOwnProperty
.Conclusion
In this benchmark, direct property access (requiredProp
) is the fastest approach, followed closely by using the in
operator with property name access (derived_requiredField
). Using the hasOwnProperty
method introduces unnecessary overhead, making derived_requiredProp
slower. These results can be useful for optimizing code that frequently accesses properties on objects.
Recommendations
in
operator with property name access when you need to check if a property exists before accessing it, but be aware of the slightly slower performance compared to direct access.hasOwnProperty
method for simple property accesses, as it introduces unnecessary overhead.Keep in mind that these results are specific to this benchmark and may not generalize to all scenarios.