in reply to Re: Faster Luhn Check Digit Calculation?
in thread Faster Luhn Check Digit Calculation?

Converted a hardcoded version of yours to Inline::C, and it's pretty much the same performance as BrowserUK's Inline::C:
$ perl ./script
Benchmark: timing 500 iterations of Inline::C (AnomalousMonk), Inline::C (BrowserUK)...
Inline::C (AnomalousMonk):  6 wallclock secs ( 6.21 usr +  0.00 sys =  6.21 CPU) @ 80.52/s (n=500)
Inline::C (BrowserUK):  6 wallclock secs ( 6.14 usr +  0.00 sys =  6.14 CPU) @ 81.43/s (n=500)
Appreciate it! Conversion below:
int cd4( char *ccn ) { int total = 0; int i; int co9[]={0,2,4,6,8,1,3,5,7,9}; int straight[]={1,3,5,7,9,11,13}; int adjusted[]={0,2,4,6,8,10,12,14}; for (i=0;i<7;i++) { total += ccn[straight[i]]-48; } for (i=0;i<8;i++) { total += co9[ccn[adjusted[i]]-48]; } total *=9; return total %10; }

Replies are listed 'Best First'.
Re^3: Faster Luhn Check Digit Calculation?
by AnomalousMonk (Archbishop) on Dec 02, 2018 at 02:25 UTC

    Here's another twist that might squeeze out a few more computrons: use array literals (if that's the correct terminology; introduced with C99 IIRC; I assume Inline::C supports C99) to compile the arrays rather than building local arrays on each subroutine call (if you don't want to just declare the arrays static| static const, which also works | should work). I haven't looked at the assembler output, but the idea (the hope?) is that the compiler would make these statics. There are two versions of the function below; both work. One is more heavily macro-ized because I wanted to see how far I could push this approach; for reasons of maintainability, I'm not sure I'd want it in production code. Only minimal testing has been done; I leave that to you :).

    t_array_literal_1.c:


    Give a man a fish:  <%-{-{-{-<