Cache the signal number or -1 in mg_private, to reduce calls to Perl_whichsig().
Nicholas Clark [Thu, 21 May 2009 06:08:53 +0000 (08:08 +0200)]
It doesn't matter that 0 isn't cacheable, as the logic in Perl_magic_setsig()
is such that we already can't "set" $SIG{ZERO}. Without this we make thousands
of failing calls to Perl_whichsig() from Perl_magic_getsig() for "__WARN__".

mg.c

diff --git a/mg.c b/mg.c
index 75fee70..43fd7ba 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -1237,10 +1237,14 @@ Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg)
 {
     dVAR;
     /* Are we fetching a signal entry? */
-    const I32 i = whichsig(MgPV_nolen_const(mg));
+    int i = (I16)mg->mg_private;
 
     PERL_ARGS_ASSERT_MAGIC_GETSIG;
 
+    if (!i) {
+       mg->mg_private = i = whichsig(MgPV_nolen_const(mg));
+    }
+
     if (i > 0) {
        if(PL_psig_ptr[i])
            sv_setsv(sv,PL_psig_ptr[i]);
@@ -1416,7 +1420,10 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
        }
     }
     else {
-       i = whichsig(s);        /* ...no, a brick */
+       i = (I16)mg->mg_private;
+       if (!i) {
+           mg->mg_private = i = whichsig(s);   /* ...no, a brick */
+       }
        if (i <= 0) {
            if (sv && ckWARN(WARN_SIGNAL))
                Perl_warner(aTHX_ packWARN(WARN_SIGNAL), "No such signal: SIG%s", s);