#!/usr/bin/perl use strict; use warnings; use Benchmark qw(cmpthese); my $code = { while_index => sub { # BrowserUk local $_ = $::TESTSTRING; s{(?:[^\cH]\cH|^\cH)}{}g while 1+index $_, chr(8); $_; }, altr_subst => sub { # smackdab local $_ = $::TESTSTRING; 1 while s/(?:[^\cH]\cH|^\cH+)//g; $_; }, noaltr_subst => sub { # smackdab local $_ = $::TESTSTRING; s/^\cH+//; 1 while s/[^\cH]\cH//g; $_; }, sexeger_while => sub { # shenme local $_ = reverse $::TESTSTRING; s{\cH[^\cH]|\cH$}{}g while 1+index $_, chr(8); scalar reverse $_; }, true_sexeger => sub { # Aristotle local $_ = reverse $::TESTSTRING; s/(\cH+)(??{ '.{0,'.length($1).'}' })//g; scalar reverse $_; }, substr => sub { # Aristotle local $_ = $::TESTSTRING; while(/([\b]+)/g) { my $len = 2 * length($1); substr($_, pos() - $len, $len, ''); } $_; }, }; $::TESTSTRING = "\bthis is an\b correct\b\b\b usage\b"; print "\nBenchmarking length ", length($::TESTSTRING), "\n"; cmpthese(-5, $code); $::TESTSTRING x= 100; print "\nBenchmarking length ", length($::TESTSTRING), "\n"; cmpthese(-5, $code); __END__
Benchmarking length 30
Benchmark: running altr_subst, noaltr_subst, sexeger_while,
substr, true_sexeger, while_index for at least 5 CPU seconds...
altr_subst:  5 wallclock secs ( 5.05 usr +  0.02 sys =  5.07 CPU) @ 35011.64/s (n=177509)
noaltr_subst:  5 wallclock secs ( 5.18 usr +  0.01 sys =  5.19 CPU) @ 143818.11/s (n=746416)
sexeger_while:  5 wallclock secs ( 5.20 usr +  0.01 sys =  5.21 CPU) @ 49023.42/s (n=255412)
substr:  5 wallclock secs ( 5.20 usr +  0.02 sys =  5.22 CPU) @ 16090.04/s (n=83990)
true_sexeger:  6 wallclock secs ( 5.30 usr +  0.02 sys =  5.32 CPU) @ 24390.23/s (n=129756)
while_index:  5 wallclock secs ( 5.29 usr +  0.03 sys =  5.32 CPU) @ 41607.89/s (n=221354)
Rate substr true_sexeger altr_subst while_index sexeger_while noaltr_subst
substr 16090/s -- -34% -54% -61% -67% -89%
true_sexeger 24390/s 52% -- -30% -41% -50% -83%
altr_subst 35012/s 118% 44% -- -16% -29% -76%
while_index 41608/s 159% 71% 19% -- -15% -71%
sexeger_while 49023/s 205% 101% 40% 18% -- -66%
noaltr_subst 143818/s 794% 490% 311% 246% 193% --
Benchmarking length 3000
Benchmark: running altr_subst, noaltr_subst, sexeger_while, substr, true_sexeger, while_index for at least 5 CPU seconds...
altr_subst:  6 wallclock secs ( 5.28 usr +  0.01 sys =  5.29 CPU) @ 411.53/s (n=2177)
noaltr_subst:  5 wallclock secs ( 5.25 usr +  0.01 sys =  5.26 CPU) @ 2662.74/s (n=14006)
sexeger_while:  5 wallclock secs ( 5.26 usr +  0.00 sys =  5.26 CPU) @ 630.80/s (n=3318)
substr:  6 wallclock secs ( 5.39 usr +  0.00 sys =  5.39 CPU) @ 167.72/s (n=904)
true_sexeger:  5 wallclock secs ( 5.39 usr +  0.02 sys =  5.41 CPU) @ 367.47/s (n=1988)
while_index:  6 wallclock secs ( 5.23 usr +  0.02 sys =  5.25 CPU) @ 516.57/s (n=2712)
Rate substr true_sexeger altr_subst while_index sexeger_while noaltr_subst
substr 168/s -- -54% -59% -68% -73% -94%
true_sexeger 367/s 119% -- -11% -29% -42% -86%
altr_subst 412/s 145% 12% -- -20% -35% -85%
while_index 517/s 208% 41% 26% -- -18% -81%
sexeger_while 631/s 276% 72% 53% 22% -- -76%
noaltr_subst 2663/s 1488% 625% 547% 415% 322% --

The winner is pretty clear. This isn't something that sexeger do much better than normal regexes either, since you need to process nested pairs of characters. It also proves once again that Perl optimization consists in offloading as much work into a single operation as possible. In C, something close to the algorithm I posted would have beaten all others; not so in Perl, where it requires that the interpreter traverse the optree and dispatch opcodes all the time, where the other solutions do a most of their work implicitly in the regex engine.

Makeshifts last the longest.


In reply to Re: should this backspace removal code be done better? by Aristotle
in thread should this backspace removal code be done better? by smackdab

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.