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:
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…
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…

Categories
Tag Cloud
Blog RSS
Comments RSS
Last 50 Posts
Back
Back
Void « Default
Life
Earth
Wind
Water
Fire
Light 