06 Jun 2009 @ 10:00 PM 

So, I’m working on a little side project at the moment… it’s a top secret, skunkworks-type thing that you can only hear about if you sign all sorts of papers and take an unmarked jet from McCarran to Area 51 :)

Because of its nature and what it has to be capable of, I have to write my code absolutely efficiently as possible. So last night I got to wondering if there was a difference in JavaScript between direct object attribute access and using accessor methods. So, is this faster…

var a = {
  attr : “frank”
};
alert(a.attr);

…or is this faster…

var MyClass = function() {
  var attr = “frank”;
  this.getAttr = function() {
    return atttr;
  }
};

Now, logically, my expectation was that the first approach would be faster. After all, there’s less code being executed and it is, deep down in the bowels of the interpreter, a much simpler operation. But, is that expectation correct? And even if it is, how big is the difference? Also, what’s the difference across various browsers? So, I threw together some very simple test code, and here it is:

Here’s the specs of the PC I ran this on:

  • Windows XP w/sp3 and all current patches as of 6/6/2009
  • Intel Core2 Duo 6600 @ 2.4GHz
  • 3G RAM
  • No applications other than browser running in foreground and all non-critical background processes shut down

And now, the results:

Firefox 3.0.10
Iterations Direct Accessor
50000 6 42
100000 12 83
200000 24 167
400000 48 331
1000000 119 826

IE 8.0.6001.18702
Iterations Direct Accessor
50000 16 63
100000 42 113
200000 87 222
400000 175 445
1000000 434 1117

Chrome 2.0.172.30
Iterations Direct Accessor
50000 1 1
100000 1 1
200000 3 2
400000 5 5
1000000 13 12

Opera 9.64 build 10487
Iterations Direct Accessor
50000 8 19
100000 16 37
200000 34 74
400000 69 147
1000000 170 367

Safari 4 public beta 528.17
Iterations Direct Accessor
50000 0 1
100000 1 2
200000 1 4
400000 3 9
1000000 7 22

All numbers are in milliseconds and have been rounded. The first number is the number of operations tests. So, that means that the test performed 50,000 operations each of direct attribute access and access via accessor method. The direct and accessor numbers are the average number of milliseconds that number of tests took, averaged over 10 test runs. So, for example, this is telling us that on Firefox 3.0.10, it took 6 milliseconds, on average, to perform 50,000 direct attribute accesses. It’s then telling us that is took 42 milliseconds, on average, to perform 50,000 attribute accessor calls.

There’s some possibly anomalous results there, although I’m convinced they aren’t incorrect. For example, in Chrome, it seems to take less time to use accessor methods when doing 200,000 or 1,000,000 iterations. I can’t imagine why that would be, but there’s the numbers. My best guess is it’s simply a rounding error and the difference is just about nothing.

There’s also the matter of that zero for the 50,000 run of direct attribute accesses for Safari. This seems to indicate that Safari is in fact the winner in terms of raw speed for direct attribute access. That’s entirely possible I think, but again, the difference between that and Chrome for the same test is probably almost nothing and it’s simply a result of rounding.

(all of this is making me wonder why I did the rounding in the first place, but I digress)

Since no report of this nature would be complete with graphs, let’s see a couple. We’ll take each of the above data sets and show them graphically (click on each to see them full-sized)…

Now let’s see a composite of all of them together, just so we can easily compare all of them…

So, what conclusions can we draw from this? I think a couple…

  • The original expectation, that direct attribute access is faster, clearly holds. Further, in all browsers except Chrome and Safari, the progression as you increase the number of iterations is almost exactly double as the number of iterations doubles.
  • Chrome performs the best, with Safari an extremly close second (not exactly surprising). Firefox and Opera are somewhat comparable, although Firefox is definitely the winner. IE is the slowest, which I think most of us would have anticipated. Even MS’s latest and greatest is pretty significantly behind all its competitors.
  • The difference in Chrome between the two methods is virtually nill. This is frankly a big surprise to me. This is nearly true of Safari as well, but not quite.
  • Even IE, the slowest of the bunch by a country mile as they say, performs a million accessor operations in just barely over a second. Slowest for sure, but still, hey, it’s a million method calls in slightly more than a second!
  • Sort of continuing the previous point… the difference, in terms of absolute milliseconds, between the two methods for any given browser (other than Chrome and Safari, which are very close to identical) isn’t generally all that much. I purposely picked pretty large numbers in terms of the number of iterations… I mean 400,000 operations a second is pretty substantial… certainly modern JavaScript can eclipse that number, absolutely. The point though is that for many types of tasks, the difference won’t matter one bit. For example, a mouse click event handler likely won’t see any sort of real-world difference between the two methods, unless you’re doing an ungodly amount of work in response to that click, in which case your design might need some rethinking anyway :)

What implications does all of this have aside from the above points? I think two important ones. First, if you want absolutely top-notch performance you’d better stick with direct attribute access regardless of browser. I don’t think this is a surprise to anyone, me included, but it’s nice to see it proven out.

Now second though, Chrome (and Safari to a slightly lesser extent) gives us a possibility we didn’t have before and don’t really have with other browsers: the chance to write our code the “right” way with no regard to performance penalties. What I mean by the “right” way is that in many ways it’s desirable to use accessor and mutator methods on a class rather than have direct attribute access to the attributes for the same reasons we do data hiding in other languages: if the only way to mutate an attribute of an object is via some mutator method, there is (theoretically at least) more safety in that. Plus, the API is arguably more self-documenting (i.e., if there is no mutator for a given attribute then we implicitly know it’s a read-only attribute). With Chrome, and almost Safari, you can write your code that way and know it won’t kill your performance. I think this is a really big step forward for us JavaScript coders. I’d also expect this to be the case with the new JS engine in Firefox, although I didn’t pull down a nightly to try it.

(and as usual, IE is the bane of our existence, but I digress once more)

So, in the end, I don’t think I made any Earth-shattering discoveries here, mostly it just confirms what I (and probably the rest of the world) already thought was the case. Still, I think seeing some hard numbers gives a clear picture of the situation and I think this was a useful exercise in the long-run.

Comments are of course welcome…

Thinks its worth sharing? Go for it:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Live
  • MySpace
  • Slashdot
  • StumbleUpon
  • email
  • Reddit
  • RSS
  • Twitter
Posted By: fzammetti
Last Edit: 06 Jun 2009 @ 10:00 PM

EmailPermalink
Tags
Categories: Uncategorized


 

Responses to this post » (None)

 
Post a Comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.


 Last 50 Posts
 Back
Change Theme...
  • Users » 1
  • Posts/Pages » 26
  • Comments » 9
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight