Performance Tuning

So I’m deep in the middle of some performance tuning work for the release of Coherent 3.0. Everyone knows that optimising Javascript is a bit of a black art, but I almost think I’m doing something wrong.

Here are the performance metrics for Coherent 2.0 running on IE 8 (in a VM):

      direct:  5.688s for 50 iterations  (Avg: 113.755ms)
     derived:  6.086s for 50 iterations  (Avg: 121.720ms)
     methods:  9.793s for 50 iterations  (Avg: 195.860ms)
      notify: 10.946s for 50 iterations  (Avg: 218.910ms)
notify class:  6.785s for 500 iterations (Avg:  13.570ms)

Coherent’s never been a stellar performer in Internet Explorer. That’s something of an understatement, but I’ve always felt the blame rested largely on IE’s craptacular Javascript engine.

Now, I’m not so sure.

Below are the same run times for the same performance tests, but this time the tests are running against the new optimised code in Coherent 3.0:

      direct:  4.309s for 50 iterations  (Avg:  86.170ms)
     derived:  0.625s for 50 iterations  (Avg:  12.500ms)
     methods:  0.910s for 50 iterations  (Avg:  18.205ms)
      notify:  8.356s for 50 iterations  (Avg: 167.110ms)
notify class:  4.547s for 500 iterations (Avg:   9.094ms)

Clearly, I’m doing something right. All the unit tests still pass. And I’m getting a 9.7× speed improvement for derived property access — that’s when accessing properties of a class derived from coherent.KVO, a 10.7× speed improvement for calling getter and setter methods, and significant 1.3× to 1.5× improvement for the other operations.

The same code running in other browsers (Safari 4.0, WebKit nightly, Firefox 3.5 and Firefox 3.6) all see speed improvements between 1.3× and 2.0×, but nothing nearly as dramatic as IE.

Below are the performance numbers from WebKit nightly running Coherent 2.0:

      direct: 304.750ms for 100 iterations  (Avg: 3.047ms)
     derived: 324.750ms for 100 iterations  (Avg: 3.248ms)
     methods: 286.250ms for 100 iterations  (Avg: 2.862ms)
      notify: 742.750ms for 100 iterations  (Avg: 7.428ms)
notify class: 257.750ms for 1000 iterations (Avg: 0.258ms)

And WebKit nightly running Coherent 3.0:

      direct: 195.500ms for 100 iterations  (Avg: 1.955ms)
     derived: 204.000ms for 100 iterations  (Avg: 2.040ms)
     methods: 213.500ms for 100 iterations  (Avg: 2.135ms)
      notify: 468.750ms for 100 iterations  (Avg: 4.688ms)
notify class: 162.500ms for 1000 iterations (Avg: 0.163ms)

This is just the result of changes to the core methods of coherent.KVO and coherent.KeyInfo. Of course, there’s still more performance tuning to come. But I don’t think I’ll have anything this dramatic to report again…