Class::XSAccessor now even faster'er

Alias on 2010-08-16T03:04:05

The new 1.07 release of Class::XSAccessor mentions the use a new somewhat-evil technique for making the code even faster than it was previously.

But how much faster is it?

The following are being run on a fairly typical corporate Windows XP machine, with Strawberry Perl 5.10.1 and thread support.

First, some benchmarks using the previous 1.05 release (two runs)

Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true...
accessor_get:  1 wallclock secs ( 2.51 usr +  0.00 sys =  2.51 CPU) @ 3976143.14/s (n=10000000)
accessor_set:  2 wallclock secs ( 3.09 usr +  0.00 sys =  3.09 CPU) @ 3233107.02/s (n=10000000)
constructor: 16 wallclock secs (15.67 usr +  0.00 sys = 15.67 CPU) @ 638080.65/s (n=10000000)
     false:  2 wallclock secs ( 1.91 usr +  0.00 sys =  1.91 CPU) @ 5243838.49/s (n=10000000)
    getter:  1 wallclock secs ( 2.34 usr +  0.00 sys =  2.34 CPU) @ 4266211.60/s (n=10000000)
 predicate:  1 wallclock secs ( 2.38 usr +  0.00 sys =  2.38 CPU) @ 4210526.32/s (n=10000000)
    setter:  2 wallclock secs ( 3.27 usr +  0.00 sys =  3.27 CPU) @ 3061849.36/s (n=10000000)
      true:  1 wallclock secs ( 1.80 usr +  0.00 sys =  1.80 CPU) @ 5564830.27/s (n=10000000)

Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true... accessor_get: 3 wallclock secs ( 2.51 usr + 0.00 sys = 2.51 CPU) @ 3976143.14/s (n=10000000) accessor_set: 3 wallclock secs ( 3.14 usr + 0.00 sys = 3.14 CPU) @ 3183699.46/s (n=10000000) constructor: 15 wallclock secs (15.73 usr + 0.00 sys = 15.73 CPU) @ 635566.29/s (n=10000000) false: 2 wallclock secs ( 1.86 usr + 0.00 sys = 1.86 CPU) @ 5379236.15/s (n=10000000) getter: 3 wallclock secs ( 2.50 usr + 0.00 sys = 2.50 CPU) @ 4000000.00/s (n=10000000) predicate: 3 wallclock secs ( 2.47 usr + 0.00 sys = 2.47 CPU) @ 4050222.76/s (n=10000000) setter: 4 wallclock secs ( 3.13 usr + 0.00 sys = 3.13 CPU) @ 3200000.00/s (n=10000000) true: 2 wallclock secs ( 1.98 usr + 0.00 sys = 1.98 CPU) @ 5037783.38/s (n=10000000)
And now again with the new 1.07 release.
Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true...
accessor_get:  2 wallclock secs ( 1.75 usr +  0.00 sys =  1.75 CPU) @ 5711022.27/s (n=10000000)
accessor_set:  1 wallclock secs ( 2.69 usr +  0.00 sys =  2.69 CPU) @ 3721622.63/s (n=10000000)
constructor: 15 wallclock secs (15.62 usr +  0.00 sys = 15.62 CPU) @ 640000.00/s (n=10000000)
     false:  1 wallclock secs ( 1.28 usr +  0.00 sys =  1.28 CPU) @ 7806401.25/s (n=10000000)
    getter:  1 wallclock secs ( 1.56 usr +  0.00 sys =  1.56 CPU) @ 6397952.66/s (n=10000000)
 predicate:  2 wallclock secs ( 1.92 usr +  0.00 sys =  1.92 CPU) @ 5205622.07/s (n=10000000)
    setter:  3 wallclock secs ( 2.50 usr +  0.00 sys =  2.50 CPU) @ 4000000.00/s (n=10000000)
      true:  2 wallclock secs ( 1.55 usr +  0.00 sys =  1.55 CPU) @ 6464124.11/s (n=10000000)

Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true... accessor_get: 2 wallclock secs ( 1.78 usr + 0.00 sys = 1.78 CPU) @ 5614823.13/s (n=10000000) accessor_set: 3 wallclock secs ( 2.63 usr + 0.00 sys = 2.63 CPU) @ 3809523.81/s (n=10000000) constructor: 16 wallclock secs (15.69 usr + 0.00 sys = 15.69 CPU) @ 637429.88/s (n=10000000) false: 2 wallclock secs ( 1.22 usr + 0.00 sys = 1.22 CPU) @ 8203445.45/s (n=10000000) getter: 2 wallclock secs ( 1.53 usr + 0.00 sys = 1.53 CPU) @ 6535947.71/s (n=10000000) predicate: 2 wallclock secs ( 1.78 usr + 0.00 sys = 1.78 CPU) @ 5614823.13/s (n=10000000) setter: 2 wallclock secs ( 2.56 usr + 0.00 sys = 2.56 CPU) @ 3903200.62/s (n=10000000) true: 2 wallclock secs ( 1.48 usr + 0.00 sys = 1.48 CPU) @ 6738544.47/s (n=10000000)
The numbers are pretty impressive.

The 'accessor', 'setter', 'predicate' and 'true' methods are about 25% faster, while 'getter' is a whopping 60% faster and (curiously) 'false' is about 50% faster as well.

Constructors are really the only thing that hasn't changed.

Impressive work, even if the code is a bit risky.


Somebody needs to fix the docs

tsee on 2010-08-16T07:51:04

Now that I read your post, I realized that the Class::XSAccessor docs still claim it's 2-3 times faster than a hand-optimized pure-Perl accessor (sub foo {$_[0]->{foo}}). According to Chocolateboy's benchmark run as well as yours, this would now be 3-4 times.

I wouldn't mind if anybody beat me to twiddling the bits in the documentation in Alias' open repository.