On Wed, 26 Sep 2001, Matt Sergeant wrote:
 
> As does backticks, surely? If you can tell me a way to make the code faster,
> damn I'll do it as we have a *lot* of emails to process :-)

maybe, i don't know in what way your code uses sv_catpv.
 
> > and who knows what else.
> 
> Nothing else. I detailed this in the thread.

yeahbut, i have not seen the code.
 
> That's not really what I was trying to say. Add some actual code to your
> test, and some printf's (and sv code to the XS) and the differences diminish
> fairly rapidly.

right, that's the flaw, you're benchmarking fprintf vs sv_catpv
 
> I was trying to say don't make the _assumption_ that XS or pure Perl code
> will be faster. 

and what i'm trying to say is that if both the xs code and external
program are doing the same thing, xs will be heaps faster than backticking
a program.  your xsub and external program are not doing the same thing.

i'm guessing part of the difference in your code is due to fprintf having
a pre-allocated buffer, whereas the SV's SvPVX has not been pre-allocated
and gets realloc-ed each time you call sv_catpv.  have a look at the code
below, fprintf is faster than sv_catpvn, but if the SvPVX is preallocated,
sv_catpvn becomes faster than fprintf:

timethese(1_000, {
    fprintf   => sub { TickTest::fprintf() },
    svcat     => sub { TickTest::svcat() },
    svcat_pre => sub { TickTest::svcat_pre() },
});

Benchmark: timing 1000 iterations of fprintf, svcat, svcat_pre...
   fprintf:  9 wallclock secs ( 8.72 usr +  0.00 sys =  8.72 CPU) @ 114.68/s (n=1000)
     svcat: 13 wallclock secs (12.82 usr +  0.00 sys = 12.82 CPU) @ 78.00/s (n=1000)
 svcat_pre:  2 wallclock secs ( 2.75 usr +  0.00 sys =  2.75 CPU) @ 363.64/s (n=1000)

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

static FILE *devnull;

MODULE = TickTest               PACKAGE = TickTest              

BOOT:
devnull = fopen("/dev/null", "w");

void
fprintf()

    CODE:
    {
        int i;
        char buffer[8292];

        for (i=0; i<sizeof(buffer); i++) {
            fprintf(devnull, "a");
        }
    }

void
svcat()

    CODE:
    {
        int i;
        char buffer[8292];
        SV *sv = newSV(0);

        for (i=0; i<sizeof(buffer); i++) {
            sv_catpvn(sv, "a", 1);
        }

        SvREFCNT_dec(sv);
    }

void
svcat_pre()

    CODE:
    {
        int i;
        char buffer[8292];
        SV *sv = newSV(sizeof(buffer)+1);

        for (i=0; i<sizeof(buffer); i++) {
            sv_catpvn(sv, "a", 1);
        }

        SvREFCNT_dec(sv);
    }


Reply via email to