11

Simple question: is there a merit of using a shallow object over a deeper one? When I write a code, I tend to use a deep object just so it is easy to understand and classify. But I am wondering if this custom is making my code slower.

I have done a test but I have no idea if I am doing it correctly.

//building necessary objects
var a = {};
var b;
b = a;
for (var i = 0; i < 100; i++) {
  b["a"] = {};
  b = b["a"];
}
var c = {};

//objects used
//a.a.a. ..(101 "a"s).. .a === {}
//c === {}

//1st test: shallow
var d;
var start = performance.now();
for (var i = 0; i < 1000000000; i++) {
  d = c;
  d = null;
}
var end = performance.now();
console.log('Shallow: ' + (end - start));

//2nd test: deeper
var e;
var start = performance.now();
for (var i = 0; i < 1000000000; i++) {
  e = a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a;
  e = null;
}
var end = performance.now();
console.log('Deeper: ' + (end - start));

the result(ms):

shallow 3229 3304 3246 3253 3277
deep    3375 3343 3247 3193 3248

The test times for the deep object is not slow, but sometimes even faster than the shallow one. Despite the result, I am not confident enough to conclude that they are the same speed. Is there any difference between two of them?

martian17
  • 418
  • 3
  • 14
  • Surely you're kidding? 1 billion operations in just over 3 seconds and you're quibbling about maybe ±100 ops? Even for a contrived worst case? This is premature optimisation writ large! The variances in implementations and systems will massively outweigh any small change in performance between the two. – RobG Sep 05 '17 at 05:15
  • Such kind of speed tests are never really usefully. You test some artificial code snippet that would never be used in such a way in real code, there is a high chance that the optimiser of a js engine would behave completely different on this example then on real code. – t.niese Sep 05 '17 at 05:19
  • Nested accesses are going to be slower generally, but the difference is too small to matter really as a property access is a fast `O(1)` operation. Note other factors and processes on your computer can contribute to those minor time differences. – Spencer Wieczorek Sep 05 '17 at 05:20
  • 1
    I think I can conclude that the speed difference is too tiny to count as a major effect because of today's advanced JS engine optimizations. – martian17 Sep 05 '17 at 07:02
  • 1
    Thank you guys for all the answers and suggestions. – martian17 Sep 05 '17 at 07:02

2 Answers2

5
  1. You are using unrealistic code to test "real code", which is nonsense
  2. You use Date.now() which is approximation to timestamp and you should use performance.now() to test js speed. Currently, even with good test code, you get wrong results.
  3. JS engines are updating all the time. There were times when deep objects were slow, it's not a case anymore for the last x years. It's such an old problem that I can't even remember the years or google anything valuable out.
Lukas Liesis
  • 24,652
  • 10
  • 111
  • 109
2

It is an optimisation in the js engine to access objects directly and allow for deep objects to be cashed in a variable which takes less time to reach. So it is faster to access them without having to go through the chain. For example:

var a={a:{a:{}}}
var b=a.a.a
var c=b
// is faster than 
var c=a.a.a

For more information read this: JavaScript Performance: Mutiple variables or one object?

user7951676
  • 377
  • 2
  • 10
  • I'm not sure what you mean here. This doesn't seem to answer the question on how slow deep nested accesses are. – Spencer Wieczorek Sep 05 '17 at 05:02
  • Are you saying OP needs to manually store the value of `a.a.a` in another variable and use that or that their engine is doing that and caching the value automatically? If you mean OP needs to do `b=a.a.a` then this is more of a work-a-around than an answer to how fast nested object accesses are. – Spencer Wieczorek Sep 05 '17 at 05:13
  • You don't know that unless you know how the compiler works in *every* implementation. For the OP's case, it **might** have realised it's more or less a no-op and optimised the whole loop away. – RobG Sep 05 '17 at 05:17
  • True but from what I know my answer is right, if you know otherwise than edit my answer or post your own – user7951676 Sep 05 '17 at 05:23
  • But the devil is in the detail. ;-) Despite the answer you referenced (and I respect the author), in some implementations around the IE 6 era it was faster to access global variables than local despite the "obvious" logic that it should be slower (haven't tested for a while so not sure if that's still true). There have been many similar examples of real world performance over the years that make me doubt any claim about speed unless there's a consistent and obvious bias across a number of popular implementations. And constant updates mean what was once slow may not be any more. ;-) – RobG Sep 05 '17 at 05:31
  • Agreed, the times the op posted may signify this – user7951676 Sep 05 '17 at 05:33