Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
Greetings fellow monks. So, earlier today in the chatterbox, someone said: "How do I get the first character from a string? I know I can reverse and chop, but there has to be an easier way." Well, this got me started thinking about the different ways that one could try to get the first character out of a string. So, I enumerated the total set I could think of, benchmarked them... and ran into a suprise that has surprised me, and baffled jeffa as well! So, let's start off with my first stab at the code, shall we?
#!/usr/bin/perl -w use strict; use Benchmark; my $string = "a man, a plan, a canal, panama!"; sub using_regexp { $string =~ /^(.)/o; return $1; } sub using_split { return (split('', $string, 2))[0]; } sub using_substring { return substr($string, 0, 1); } sub using_unpack { return unpack('A1', $string); } sub using_reverse_chop { return chop reverse $string; } timethese(-5, {'Using Regexp' => \&using_regexp, 'Using Split' => \&using_split, 'Using Substring' => \&using_substring, 'Using Unpack' => \&using_unpack, 'Using Reverse & Chop' => \&using_reverse_chop, });
Seems reasonable enough, does it not? I think that they are relatively optimized versions of each method... and then, a surprise struck.
[earino@localhost earino]$ ./first_char.pl Can't modify reverse in chop at ./first_char.pl line 27, near "$string +;" Execution of ./first_char.pl aborted due to compilation errors. [earino@localhost earino]$
Eek! What was that??? Can't modify reverse in chop... well, I wasn't trying to modify reverse, I was string to modify the reversed string. So, I did what any reasonable man with highly brilliant friends would do... I asked maverick... but he was in the shower :) So, jeffa was next... our first stab at it was:
return chop reverse scalar $str;
Which met with the same exact amount of success. After trying a few other things, we decided that this was a question better left for Seekers of Perl Wisdom... and let some of the wizards slap us a bit and tell us what we were doing wrong. So, undaunted by this first whack at the problem, I decided that I *still* wanted to benchmark the possible ways to get the first char out of a string, so this was my slightly lobotomized version 2 of the code (only change was in using_reverse_chop):
#!/usr/bin/perl -w use strict; use Benchmark; my $string = "a man, a plan, a canal, panama!"; sub using_regexp { $string =~ /^(.)/o; return $1; } sub using_split { return (split('', $string, 2))[0]; } sub using_substring { return substr($string, 0, 1); } sub using_unpack { return unpack('A1', $string); } sub using_reverse_chop { my $str = reverse $string; return chop $str; } timethese(-5, {'Using Regexp' => \&using_regexp, 'Using Split' => \&using_split, 'Using Substring' => \&using_substring, 'Using Unpack' => \&using_unpack, 'Using Reverse & Chop' => \&using_reverse_chop, });
As you can see, all I did was add a temporary value to store the reversed string... and though this was functional, I felt that it made it relatively useless for benchmarking, as I had the overhead of a brand new variable being created each time. So, I ran the benchmark for a minimum of 5 seconds of CPU time...the results are as follows:
Benchmark: running Using Regexp, Using Reverse & Chop, Using Split, Us +ing Substring, Using Unpack, each for at least 5 CPU seconds... Using Regexp: 5 wallclock secs ( 5.39 usr + -0.01 sys = 5.38 CPU) @ +207251.30/s (n=1115012) Using Reverse & Chop: 4 wallclock secs ( 5.23 usr + 0.00 sys = 5.23 + CPU) @ 255457.74/s (n=1336044) Using Split: 5 wallclock secs ( 5.25 usr + 0.01 sys = 5.26 CPU) @ 9 +7116.92/s (n=510835) Using Substring: 5 wallclock secs ( 5.25 usr + -0.02 sys = 5.23 CPU) + @ 1009882.22/s (n=5281684) Using Unpack: 5 wallclock secs ( 5.27 usr + 0.01 sys = 5.28 CPU) @ +260676.33/s (n=1376371)
And that, is just ugly... so, here is a nice table version of that...

MethodIterations
Regexp1,115,012
Reverse & Chop1,336,044
Split510,835
Substring5,281,684
Unpack1,376,371

So! Far and away, substring is the winner... which I guess makes sense, when you realize that substr is a function that exists to... well, get a substring! And getting the first character out of a string is pretty much a textbook case of that. The only real surprises were how *really* bad split did... but it makes sense, as it's creating a list. And how surpsisingly good R&C did even though I had to use a temporary variable (then again, I bet perl is incredibly smart about keeping that area of memory around handy in case it is needed again eh?) So... what's the moral of the story? Use the right tool for the right job. If you need a substring, use substr. And anyone that can explain to me why R&C failed, I'd love to hear it.

In reply to First char out of a string & surprises with errors on chop reverse $string (that doesn't work!) by eduardo

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



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (2)
As of 2024-04-25 20:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found