Revision: 1018
Author: [email protected]
Date: Tue Jan 19 08:22:24 2010
Log: A slightly tighter implementation normalize_eval_seqn(), which assumes that
memchr() and memmove() are faster than C loops, and avoids moving strings if
the edit leaves the string with the same length.
http://code.google.com/p/perl-devel-nytprof/source/detail?r=1018

Modified:
 /trunk/NYTProf.xs

=======================================
--- /trunk/NYTProf.xs   Mon Jan 18 08:56:42 2010
+++ /trunk/NYTProf.xs   Tue Jan 19 08:22:24 2010
@@ -3361,41 +3361,63 @@
 static void
 normalize_eval_seqn(pTHX_ SV *sv) {
     /* in-place-edit any eval sequence numbers to 0 */
-    int found = 0;
     STRLEN len;
     char *start = SvPV(sv, len);
-    char *src = start;
-    char *dst = start;
-
-    if (len < 5)
-        return;
-
-    /* effectively does $sv =~ s/(?<!$assert) \s \d+/eval 0/xg;
- * where $assert is qr/\((?:re_)?eval/ so it only matches '(eval ' and '(re_eval '
-     */
-    while (*src) {
-        if (*src == ' ' && isdigit(*(src+1)) &&
-            (  (src-start >= 5 && strnEQ(src-5,    "(eval ", 6))
-            || (src-start >= 8 && strnEQ(src-8, "(re_eval ", 8)) )
-        ) {
-            ++found;
-            if (trace_level >= 5)
-                logwarn("found eval at '%s' in %s\n", src, start);
-            *dst++ = ' ';
-            *dst++ = '0';
-             src++; /* skip space */
-             src++; /* skip first digit */
-            while (isdigit(*src)) { /* skip any extra digits */
-                ++src;
-            }
-        }
-        else {
-            *dst++ = *src++;
-        }
-    }
-    if (found) {
-        *dst++ = '\0';
-        SvCUR_set(sv, strlen(start));
+    char *first_space;
+
+    /* effectively does
+       s/(
+          \(                  # first character is literal (
+          (?:re_)?eval\       # eval or re_eval followed by space
+         )                    # [capture that]
+         [0-9]+               # digits
+         (?=\))               # look ahead for literal )
+         /$1 0/xg             # and rebuild, replacing the digts with 0
+    */
+
+ /* Assumption is that space is the least common character in a filename. */
+
+    for (; len >= 8 && (first_space = memchr(start, ' ', len));
+         (len -= first_space - start - 1), (start = first_space + 1)) {
+        char *first_digit;
+        char *close;
+
+        if (!((first_space - start >= 5
+               && memEQ(first_space - 5, "(eval", 5))
+              || (first_space - start >= 8
+                  && memEQ(first_space - 8, "(re_eval", 8)))) {
+            /* Fixed string not found. Try again.  */
+            continue;
+        }
+
+        first_digit = first_space + 1;
+        if (*first_digit < '0' || *first_digit > '9')
+            continue;
+
+        close = first_digit + 1;
+
+        while (*close >= '0' && *close <= '9')
+            ++close;
+
+        if (*close != ')')
+            continue;
+
+        if (trace_level >= 5)
+            logwarn("found eval at '%s' in %s\n", first_digit, start);
+
+        *first_digit++ = '0';
+
+        /* first_digit now points to the target of the move.  */
+
+        if (close != first_digit) {
+            /* 2 or more digits */
+            memmove(first_digit, close,
+                    start + len + 1 /* pointer beyond the trailing '\0'  */
+                    - close);       /* pointer to the )  */
+
+            SvCUR_set(sv, len - (close - first_digit));
+        }
+
         if (trace_level >= 5)
             logwarn("edited it to: %s\n", start);
     }
-- 
You've received this message because you are subscribed to
the Devel::NYTProf Development User group.

Group hosted at:  http://groups.google.com/group/develnytprof-dev
Project hosted at:  http://perl-devel-nytprof.googlecode.com
CPAN distribution:  http://search.cpan.org/dist/Devel-NYTProf

To post, email:  [email protected]
To unsubscribe, email:  [email protected]

Reply via email to