develooper Front page | perl.perl5.porters | Postings from March 2007

Re: The performance problem of 30678

Thread Previous
From:
Marcus Holland-Moritz
Date:
March 24, 2007 09:29
Subject:
Re: The performance problem of 30678
Message ID:
20070324172905.46337e6a@r2d2
On 2007-03-24, at 15:06:23 +0000, Nicholas Clark wrote:

> On Sat, Mar 24, 2007 at 08:22:13AM +0100, Rafael Garcia-Suarez wrote:
> 
> Or are we just bumping the refcounts through the roof?

You mean like refcounts of half a million?

Indeed. :-)

Here's some annotated code from cachegrind:

            .         .     .             .          .       .           .      .      .  regexp *
    2,658,965   531,711     0             0          0       0   1,595,379      0      0  Perl_reg_temp_copy (pTHX_ struct regexp *r) {
            .         .     .             .          .       .           .      .      .      regexp *ret;
    2,127,172         0     0     1,063,586     94,146      25     531,793      0      0      register const I32 npar = r->nparens+1;
    3,722,551   531,728     7     2,127,172     31,463       0     531,793      0      0      (void)ReREFCNT_inc(r);
    1,595,379         0     0             0          0       0   1,595,379      0      0      Newx(ret, 1, regexp);
   15,953,790   531,727    13    13,826,618     21,510      50  12,763,032 70,941     55      StructCopy(r, ret, regexp);
   12,763,032 1,063,490    23     2,658,965    341,277       0   2,658,965      0      0      Newx(ret->startp, npar, I32);
   14,358,411 1,595,309    25     4,254,344          0       0   3,190,758      0      0      Copy(r->startp, ret->startp, npar, I32);
   12,763,032 1,595,303    14     2,658,965          0       0   2,658,965      0      0      Newx(ret->endp, npar, I32);
   14,358,411 1,595,133    14     4,254,344          0       0   3,190,758      0      0      Copy(r->endp, ret->endp, npar, I32);
    1,063,586         0     0       531,793          0       0     531,793      0      0      ret->refcnt = 1;
    2,127,172         0     0     1,063,586          0       0           0      0      0      if (r->substrs) {
            .         .     .             .          .       .           .      .      .          struct reg_substr_datum *s;
            .         .     .             .          .       .           .      .      .          I32 i;
    2,658,965   531,793     8       531,793          0       0   1,595,379      0      0          Newx(ret->substrs, 1, struct reg_substr_data);
   10,104,067 1,063,531    13     6,381,516          0       0   1,063,586      0      0          for (s = ret->substrs->data, i = 0; i < 3; i++, s++) {
   15,953,790   531,793     6     7,976,895      9,438      31   1,595,379 53,536      4              s->min_offset = r->substrs->data[i].min_offset;
   19,144,548   531,703    10     7,976,895         20      15   1,595,379 12,325      5              s->max_offset = r->substrs->data[i].max_offset;
   19,144,548   531,703    10     7,976,895      6,522      21   1,595,379 46,808     65              s->end_shift  = r->substrs->data[i].end_shift;
   40,413,676 1,063,586    16    19,674,721        528      13   5,849,399      0      0              s->substr     = SvREFCNT_inc(r->substrs->data[i].substr);
   31,907,660 1,063,518    14    14,358,461          5       0   4,786,147      0      0              s->utf8_substr = SvREFCNT_inc(r->substrs->data[i].utf8_substr);
            .         .     .             .          .       .           .      .      .          }
            .         .     .             .          .       .           .      .      .      }        
    3,190,758   531,709     7     1,595,379          0       0     531,793      0      0      RX_MATCH_COPIED_off(ret);
            .         .     .             .          .       .           .      .      .  #ifdef PERL_OLD_COPY_ON_WRITE
            .         .     .             .          .       .           .      .      .      /* this is broken. */
            .         .     .             .          .       .           .      .      .      assert(0); 
            .         .     .             .          .       .           .      .      .      if (ret->saved_copy)
            .         .     .             .          .       .           .      .      .          ret->saved_copy=NULL;
            .         .     .             .          .       .           .      .      .  #endif
    1,595,379         0     0     1,063,586          0       0     531,793      0      0      ret->mother_re = r; 
    1,063,586   531,772     1       531,793          0       0     531,793      0      0      ret->swap = NULL;
            .         .     .             .          .       .           .      .      .      
      531,793         0     0       531,793          0       0           0      0      0      return ret;
    2,658,965         0     0     2,127,172          0       0           0      0      0  }
            .         .     .             .          .       .           .      .      .  #endif


As you can see, it spends quite a couple of cycles in the
SvREFCNT_inc() lines. Instrumenting the code I can see the
refcount for s->substr go way over 500000 for the CURLYX
stress test. This matches perfectly with S_visit being called
just that many times.

Hope that does ring some bells. Maybe there's code missing
somewhere to drop the refcounts again?

Marcus

-- 
Data, n.:
	An accrual of straws on the backs of theories.

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About