In my interfacing to my library I am starting hit performance issues
related to extracting values from the library and passing to perl.

Before I start profiling I thought I would look at the code, so in XS
(for a very simple function call):

double
fffixr(d)
double d;

Which becomes this in the resultant C file:


XS(XS_FF_fffixr); /* prototype to pass -Wmissing-prototypes */
XS(XS_FF_fffixr)
{
    dXSARGS;
    if (items != 1)
        Perl_croak(aTHX_ "Usage: FF::fffixr(d)");
    {
        double  d = (double)SvNV(ST(0));
        double  RETVAL;
        dXSTARG;

        RETVAL = fffixr(d);
        XSprePUSH; PUSHn((double)RETVAL);
    }
    XSRETURN(1);
}

Which expands out to this monstrosity in actual naked C code:

void XS_FF_fffixr(register PerlInterpreter *my_perl __attribute__((unused)), 
CV* cv)
{
    register SV **sp = (*Perl_Tstack_sp_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))))); register SV **mark 
= (*Perl_Tstack_base_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))))) + 
(*(*Perl_Tmarkstack_ptr_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0)))))))--); I32 ax = mark - 
(*Perl_Tstack_base_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))))) + 1; I32 items = sp 
- mark;
    if (items != 1)
 Perl_croak(((PerlInterpreter *)pthread_getspecific((*Perl_Gthr_key_ptr(((void 
*)0))))), "Usage: FF::fffixr(d)");
    {
 double d = (double)((((*Perl_Tstack_base_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0)))))))[ax + 
(0)])->sv_flags & 0x00020000) ? 
((XPVNV*)((*Perl_Tstack_base_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0)))))))[ax + 
(0)])->sv_any)->xnv_nv : Perl_sv_2nv(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))), 
(*Perl_Tstack_base_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0)))))))[ax + (0)]));
 double RETVAL;
 SV * targ = (((*Perl_Top_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0)))))))->op_private & 32) ? 
((*Perl_Tcurpad_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void 
*)0)))))))[(*Perl_Top_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0)))))))->op_targ]) : 
Perl_sv_newmortal(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0)))))));

 RETVAL = fffixr(d);
 (sp = (*Perl_Tstack_base_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))))) + ax - 1); (void)( 
{ Perl_sv_setnv(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))), 
targ,(NV)((double)RETVAL)); (void)( { (void)( { if (((targ)->sv_flags & 
0x00004000)) Perl_mg_set(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))), targ); } ); (*++sp = 
(targ)); } ); } );
    }
    (void)( { IV tmpXSoff = (1); (*Perl_Tstack_sp_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))))) = 
(*Perl_Tstack_base_ptr(((PerlInterpreter 
*)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))))) + ax + (tmpXSoff - 
1); return; } );
}

Questions:

1. Why on earth don't the macros change on non-threaded perls (like wot I am 
using)?
2. Why are they inline when they really could(/should) be functions if they are 
this big?
3. All my tests (elsewhere) say that 'register' is slower than allowing gcc to 
optimize?  

Dirk

Reply via email to