<?xml version="1.0" encoding="windows-1252"?>
<node id="513577" title="Re: Speed/Efficiency tweaks for a fannkuch benchmark script?" created="2005-12-02 07:37:59" updated="2005-12-02 02:37:59">
<type id="11">
note</type>
<author id="117983">
robin</author>
<data>
<field name="doctext">
I can squeeze another 20% or so out of it – actually 23% on my systems – with some more micro-optimizations. The most significant change is in the inner loop, where I’ve changed
&lt;code&gt;
  substr( $q, 0, $k ) = reverse substr( $q, 0, $k );
&lt;/code&gt;
to
&lt;code&gt;
  $q = reverse(substr($q, 0, $k)) . substr($q, $k);
&lt;/code&gt;
Here's the code:
&lt;code&gt;
sub fannkuch {
    use bytes;    # This makes it fractionally faster
    my ( $copy, $level, $split ) = ( @_, 0, 1 );
    my ( $index, $next, $length ) = ( $level, $level + 1, length( $copy ) );

    if ($next == $length) {
        $index = $split - 1;
        substr($copy, $index, 0) = chop($copy);
    }

    my ( $q, $k );
    do {
        if ($next == $length) {
            if (($k = ord($q = $copy)) != $length
            ||  $level &gt;= $maxflips)
            {
                # Declaring $flips in here means we can reset it
                # with a single op (compared with the three you
                # need for C&lt;$flips = 0&gt;).
                my $flips;

                # This is a touch faster than a "proper" loop,
                # because it doesn't push a new context.
                  $q = reverse(substr( $q, 0, $k )) . substr($q, $k),
                  ++$flips
                while ($k=ord($q)) != 1;

                no warnings "uninitialized"; # $flips may be undef
                if ( $flips &gt;= $maxflips ) {
                    if ( $flips == $maxflips) {
                        push @max_sequence, $copy;
                    }
                    else {
                        ($maxflips, @max_sequence) = ($flips, $copy);
                    }
                }
            }
        }
        else {
            fannkuch( $copy, $next, $split );
            $split = $next if $index == $split;
        }
        substr($copy, $index-1, 2) = reverse substr($copy, $index-1, 2);

    } while $index--;
    $maxflips;  # faster than an explicit return
}
&lt;/code&gt;</field>
<field name="root_node">
513179</field>
<field name="parent_node">
513179</field>
</data>
</node>
