on 11/14/2000 11:19 PM, Ronald J Kimball at rjk@linguist.dartmouth.edu wrote: >>> The difference between using s/// and tr/// is actually rather significant. >> >> Is it possible to write the >> >> s/([a-z0-9])/$replace{$1}/g; >> >> in a tr/// form? It's my understanding at this point (and I could be wrong) >> that you have to write it as an eval, but I don't know whether you can >> assign the result of that to a variable, using =~ .. anyone know? > > Yup, you're right, you do need eval to use non-constant strings in tr///. > But fortunately, you only need the eval to be executed once. For example: > > my $reverse = reverse '0' .. '9', 'a'..'z'; > my $trans = eval "sub { \$_[0] =~ tr/a-z0-9/$reverse/ }"; It wouldn't have occurred to me to put the reference where you did.. can you give me a clue or two as to why it's done that way instead of referencing the anonymous sub itself? > while (<DATA>) { > $trans->($_); > print; > } > > That creates a reference to an anonymous subroutine that, when called, > performs the translate on the first argument. > > Then, to avoid so many subroutine dereferences and calls, you can put the > loop inside the eval. And if you're only going to execute the loop once, > you don't need the anonymous sub, of course; you can just eval the code > directly. (See TransSub2 below for an example of that.) hmm. I think, as I mention below, that it'd be $trans1 that I would use, however it occurs to me that you might have yet another trick to use, that would work in the context of my code. see my previous post to the list for the url. > And here's another benchmark, with various eval approaches: > > > Benchmark: timing 8192 iterations of Substitute, Trans, TransEval, > TransSub1, TransSub2... > Substitute: 26 wallclock secs (24.58 usr + 0.04 sys = 24.62 CPU) > Trans: 2 wallclock secs ( 1.30 usr + 0.01 sys = 1.31 CPU) > TransEval: 4 wallclock secs ( 3.96 usr + 0.01 sys = 3.97 CPU) > TransSub1: 2 wallclock secs ( 2.08 usr + 0.00 sys = 2.08 CPU) > TransSub2: 2 wallclock secs ( 1.22 usr + 0.00 sys = 1.22 CPU) whew. 'nuff said. what computer are you running there anyway? (just curious) > #!perl -w > use strict; > use Benchmark; > > my @DATA = <DATA>; > my @tmp; > > my %replace; > > @replace{'a' .. 'z'} = reverse 'a' .. 'z'; > @replace{'0' .. '9'} = reverse '0' .. '9'; > > my $reverse = reverse '0' .. '9', 'a'..'z'; ok, now I know how to do that the way I want it. *scribbling notes* > my $trans1 = eval "sub { \$_[0] =~ tr/a-z0-9/$reverse/ }"; > my $trans2 = eval "sub { foreach (\@_) { tr/a-z0-9/$reverse/ } }"; nice trick, both of them, although for my purposes I'd probably use trans1 since the loop around the data does several other things, and since it's a complex HOHOL, this isn't the easiest thing to look through as if it were a simple array, NOR does it make sense for me to dump out the data INTO an array and sort THAT due to the flow of the program. (I'm actually using the loop to build the keys of the HO(H)OL at that point) So, $trans1 it is. :) See my previous post to the list for the url to download the script if you are curious enough to want to check it out yourself. I figured that would be smarter than spamming it to everyone on the list. >:) > timethese(1 << (shift || 0), > { > 'Substitute' => > sub { > for (@tmp = @DATA) { > s/([a-z0-9])/$replace{$1}/g; > } > }, > 'Trans' => > sub { > for (@tmp = @DATA) { > tr/abcdefghijklmnopqrstuvwxyz0123456789/zyxwvutsrqponmlkjihgfedcba9876543210/; > # damn linewrapping :-| > } > }, > 'TransEval' => > sub { > eval "for (\@tmp = \@DATA) { \$_ =~ tr/a-z0-9/$reverse/ }"; > }, > 'TransSub1' => > sub { > for (@tmp = @DATA) { > $trans1->($_); > } > }, > 'TransSub2' => > sub { > $trans2->(@tmp = @DATA); > }, > } > ); > [snippage] >> Considering I have around 2,630 map names to deal with at present, I'm still >> not certain how much time it saves or not. the .cgi SEEMS to still run >> generally as fast as usual, only taking about 5 secs to iterate through the >> largest segment of the maplist (the UT Deathmatch maps; around 1600-1700 or >> so); the part that takes it the longest, is sending the actual HTML for this >> portion, which tops out around 500K+ > > In the Benchmark results above, each approach did tr/// on more than > 200,000 lines. Even though the Substitute method is an order of magnitude > slower, that's only half a second for 2,630 lines. So, you're not looking > at a big time savings in that area. ok, but I'll definitely keep this information in mind as the list of maps continues to grow daily, and I'm thinking of incorporating the Unreal 1 maps as well as the Unreal Tournament maps into the script, as I can run database checks on them as well, for errata and whatnot (even if I don't use the resultant data in my CGI). -- Scott R. Godin | e-mail : mactech@webdragon.net Laughing Dragon Services | web : http://www.webdragon.net/ # ===== Want to unsubscribe from this list? # ===== Send mail with body "unsubscribe" to macperl-request@macperl.org