Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Alias (5735)

Alias
  (email not shown publicly)
http://ali.as/

Journal of Alias (5735)

Sunday August 15, 2010
10:04 PM

Class::XSAccessor now even faster'er

[ #40497 ]

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.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • 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.