Web Developer's Virtual Library: Encyclopedia of Web Design Tutorials, Articles and Discussions


WDVL Newsletter

Active Server Pages
JSP/Java Servlets
Microsoft SQL Server
Daily Backup
Dedicated Servers
Streaming Audio/Video
24-hour Support    

jobs.webdeveloper.com

Hiermenus


e-commerce
Partner With Us















Developer Channel
FlashKit.com
JavaScript.com
JavaScriptSource
Developer Jobs
ScriptSearch
StreamingMediaWorld
Web Developer's Journal
Web Developer's Virtual Library
WebDeveloper.com
Webreference
Web Hosts
XMLfiles.com

internet.com
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers


Apples to Apples, Oranges to Oranges - Page 158

January 22, 2001

In learning to use Benchmark's timethis function, we wound up comparing the speed of several solutions. In fact, the Benchmark module provides a ready-made comparison function that can make measurements of several solutions even simpler. This time, let's imagine a case where we want to code a subroutine that will accept a string value, and return a string value consisting of the character codes for each character in the original string, separated by spaces.

For example, the string "A" would, when passed through this subroutine, be returned merely as "65". The string "AB" would be returned as "65 66", and so on.

Once again, thanks to the versatility of Perl, we can let our imagination run wild — but not too wild. Just wild enough, for now, to generate three plausible subroutines to solve this case.

The first, wordOrd_a, splits the incoming string into a list of letters, iterates through that list, pushing the character code for each letter (via the ord function) onto a new list. Finally, it returns a scalar by joining the elements of the new list.

wordOrd_a

sub wordOrd_a {
 my ($word)=@_;
 my @ordStr=();
 foreach my $letter (split //,$word) {
  push (@ordStr,ord($letter));
 }
 return join(" ",@ordStr);
}

The second candidate, wordOrd_b, is nearly identical to the first candidate, but substitutes the Perl map function for the foreach loop that we relied on in the first attempt.

wordOrd_b

sub wordOrd_b {
my ($word)=@_; my @ordStr=(); @ordStr=map { ord $_ } split //,$word; return join (" ",@ordStr); }

The third candidate is super-compact, doing away with the split entirely and instead using Perl's unpack method in a technique gleaned gleefully from the ord synopsis on page 114 of Perl in a Nutshell (O'Reilly & Associates, 1998). We also dropped the interim variable $word and instead refer to the first item in the incoming parameter list directly.

wordOrd_c

sub wordOrd_c {
         return join (" ",unpack('C*',$_[0]));
}
Now, for the race. With all three subroutines revved up and raring to go, we can call upon Benchmark's cmpthese function to test and compare the execution times of the three candidates, resulting in a revealing summary table.
use Benchmark;


my $count=500000;
my $testStr="green apples and yellow oranges, oh my";
&Benchmark::cmpthese($count,
{ wordOrd_a => q/my $val=&wordOrd_a($testStr)/, wordOrd_b => q/my $val=&wordOrd_b($testStr)/, wordOrd_c => q/my $val=&wordOrd_c($testStr)/, } );
The computer begins to whir, steam, and belch, and in an exhausted heap dutifully reports its tally:
Benchmark: timing 500000 iterations of wordOrd_a,
	wordOrd_b, wordOrd_c...
 wordOrd_a:  4 wallclock secs ( 3.55 usr +
 	0.00 sys =  3.55 CPU) @ 141003.95/s
(n=500000)
 wordOrd_b:  2 wallclock secs ( 2.54 usr +
 	0.00 sys =  2.54 CPU) @ 196540.88/s
(n=500000)
 wordOrd_c:  2 wallclock secs ( 1.64 usr +
 	0.00 sys =  1.64 CPU) @ 304506.70/s
(n=500000)
              Rate wordOrd_a wordOrd_b wordOrd_c
wordOrd_a 141004/s        --      -28%      -54%
wordOrd_b 196541/s       39%        --      -35%
wordOrd_c 304507/s      116%       55%        --
The winner, not surprisingly, is the code that appeared most efficient: version c, the unpack solution. Indeed, from the numbers we can see that wordOrd_c ran 304,506.70 times per second, quite a bit faster than the closest competitor in wordOrd_b. The nifty table provided by cmpthese displays the results in startling percentages: wordOrd_c was 116% faster than wordOrd_a and 55% faster than wordOrd_b.

Once again, we see that there can be significant differences between approaches to the same problem in Perl — hopefully compelling enough numbers to convince the Web developer to take benchmarking seriously. Visitors to a Web site never like to wait, no matter how much magical hoo-hah the back-end script is performing. Given the causes of delay that are difficult to control, such as network traffic and latency, and the flexibility of Perl, it makes that much more sense to optimize the slowest portions of your own code.

Out of the Starting Block - Page 157
The Perl You Need to Know
Run-time Timing - Page 159


Up to => Home / Authoring / Languages / Perl / PerlfortheWeb




Jupiter Online Media: internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and Jupiter Online Media

Jupitermedia Corporate Info


Legal Notices, Licensing, & Permissions, Privacy Policy.

Web Hosting | Newsletters | Tech Jobs | Shopping | E-mail Offers