c:\test>mathbcd Comparing incrementing 100_000 digit numbers; 10,000 iterations. (warning: too few iterations for a reliable count) s/iter magic bcd magic 1.66 -- -100% bcd 6.20e-003 26740% -- 1000000000 ... 0000099999 1000000000 ... 0000099999 Comparing incrementing 1_000_000 digit numbers; 10,000 iterations (warning: too few iterations for a reliable count) s/iter magic bcd magic 17.4 -- -100% bcd 9.40e-003 185072% -- 1000000000 ... 0000099999 1000000000 ... 0000099999 Comparing incrementing 10_000_000 digit numbers; 10,000 iterations (warning: too few iterations for a reliable count) ** The BCD finishes in a second or so, but I gave up waiting for the magic to finish after it had thrashed my machine for more than an hour ** #### #! perl -slw package Math::BCD; use strict; use Inline C => << 'EOC', NAME => 'Math::BCD', CLEAN_AFTER_BUILD => 0; void _prep( SV *self ) { U32 len; char *p = SvPV( SvRV( self ), len ); for( ; len--; *p++ -= 48 ); } void inc( SV *self ) { U32 l; SV *n = SvRV( self ); char *a = SvPV( n, l ); if( *a == 9 ) { if( SvOOK( n ) && ( SvIV( n ) > 0 ) ) { SvLEN_set( n, SvLEN( n ) +1 ); SvCUR_set( n, ++l ); SvPV_set( n, --a ); SvIVX( n )--; } else { char pad[100] = { 0, }; sv_insert( n, 0, 0, pad, 100 ); sv_chop( n, SvPVX( n ) + 99 ); a = SvPVX( n ); ++l; } } a += l - 1; _asm { pushad; mov esi, a; mov al, 1; add al, [esi]; aaa; mov [esi], al jnc $1; $0: dec esi; adc al, [esi]; aaa; mov [esi], al; jc $0; $1: popad; } return; } SV *asString( SV *self ) { SV *copy = newSVsv( SvRV( self ) ); U32 l; char *p = SvPV( copy, l ); for( ; l--; *p++ += 48 ); return copy; } EOC sub new { my( $class, $init ) = @_; my $self = bless \$init, $class; $self->_prep; return $self; } package main; use Benchmark qw[ cmpthese ]; for my $len ( 1e5, 1e6, 1e7 ) { our $number = '9' x $len; our $bcd = new Math::BCD( $number ); print "\nComparing incrementing $len digit numbers"; print "10 thousand iterations of Perl's magic string increment against"; print "10 million iterations of using BCD and assembler"; cmpthese 10, { magic => q[ ++$number for 1 .. 1e3 ], bcd => q[ $bcd->inc for 1 .. 1e6 ], }; print substr( $number, 0, 10 ), ' ... ', substr $number, -10; print substr( $bcd->asString, 0, 10 ), ' ... ', substr $bcd->asString, -10; } __END__ c:\test>mathbcd Comparing incrementing 100000 digit numbers 10 thousand iterations of Perl's magic string increment against 10 million iterations of using BCD and assembler Rate bcd magic bcd 1.48/s -- -76% magic 6.22/s 320% -- 1000000000 ... 0000009999 1000000000 ... 0009999999 Comparing incrementing 1000000 digit numbers 10 thousand iterations of Perl's magic string increment against 10 million iterations of using BCD and assembler s/iter magic bcd magic 1.72 -- -60% bcd 0.695 148% -- 1000000000 ... 0000009999 1000000000 ... 0009999999 Comparing incrementing 10000000 digit numbers 10 thousand iterations of Perl's magic string increment against 10 million iterations of using BCD and assembler s/iter magic bcd magic 17.2 -- -96% bcd 0.723 2273% -- 1000000000 ... 0000009999 1000000000 ... 0009999999