Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

code execution speed and variable name length

by zentara (Archbishop)
on Jul 29, 2004 at 13:51 UTC ( #378376=perlquestion: print w/replies, xml ) Need Help??

zentara has asked for the wisdom of the Perl Monks concerning the following question:

Hello again. When I first started learning Perl, the word "hash" struck me with awe and 'fear of syntax'. Now I find them to be the best feature of Perl.

Recently I've taken up the habit of using hashes to hold my variables, and using really descriptive long names in the hash keys. My question is, does this affect the execution speed of the code? I can see there may be a slight hit while loading the bigger script file, but does perl care internally? How much of a problem does this practice cause? Is there a limit where it starts to cause slowdowns?

For instance, is one hash scheme better than the other in the following:

$game{'placedtiles'}{$currentuser}{$localrow}{$localcol} #vs $g{'pt'}{$cu}{$lr}{$lc}

I'm not really a human, but I play one on earth. flash japh

Replies are listed 'Best First'.
Re: code execution speed and variable name length
by QM (Parson) on Jul 29, 2004 at 13:57 UTC
    use Benchmark qw(timethese);

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

Re: code execution speed and variable name length
by demerphq (Chancellor) on Jul 29, 2004 at 17:04 UTC

    Keys are calculated by amalgamating the values of the chars in the key. Accordingly there will be a run time cost for using longer keys. However I should think that on modern PC's you will find that the keys would have to be very long before the difference was measureable. The actual C code used to calculate the key is in the following readmore:

    For the example you posted 'placedtiles' versus 'pt' i should think the difference would be negligable for most applications. Also as another poster stated you'll see no difference at runtime with using longer var names and shorter ones. Its very unlikely that you will notice a startup cost for longer vars, but it is possible mostly for IO reasons I should think. OTOH you'll almost certainly notice maintainance issues with the short names. IMO the cost/benefit breakdown will in almost all circumstances be in favour of using longer more descriptive names for both hash keys and var names. If you really need it to be faster then switch to using arrays or switch to using C.

    BTW, i think this is an appropriate time to bring up the old adage: "Premature optimisation is bad." Get the code working then profile it to identify optimisation targets if you really need it to be faster.


    ---
    demerphq

      First they ignore you, then they laugh at you, then they fight you, then you win.
      -- Gandhi


Re: code execution speed and variable name length
by dragonchild (Archbishop) on Jul 29, 2004 at 14:15 UTC
    I haven't benchmarked this, so you should take this with a grain of salt. But, I would be extremely surprised if you found more than a 1% difference in execution time for any non-trivial application.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

      1% is not detectable with standard tools like Benchmark. How big would the difference have to be before it could be considered detectable?
        I would say that anything under 5% is noise and is almost always safely ignorable. (Obviously, 1% for Amazon, EBay, or Google isn't ignorable, but I don't think any of us have that kind of demand.) Of course, this is a rule of thumb with the appropriate caveats about such.

        Furthermore, I don't think benchmarking variable name length isn't worthwhile, for the simple reason that Perl itself is a poor choice for execution speed. If you have optimized your Perl code to the point that the only thing you can think to do is reduce the size of your variable names and you still need to optimize further, then you need to look at rewriting some of your Perl in XS and/or C. If that doesn't help, rewrite the rest of your Perl in C and optimize some of your C to ASM. If that doesn't work, you need bigger servers.

        In other words, micro-optimizations like that are cases of premature optimization and should be avoided. But, then again, you already knew that. :-)

        ------
        We are the carpenters and bricklayers of the Information Age.

        Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

        I shouldn't have to say this, but any code, unless otherwise stated, is untested

Re: code execution speed and variable name length
by fletcher_the_dog (Friar) on Jul 29, 2004 at 16:38 UTC
    I have only looked at perl internals briefly, but my guess is that it makes no difference, especially when you are using 'my' variables. The reason I say this is that from my limited knowledge of compilers, lexical variables usally are just used for the compiler which converts them to some type of internal represention that doesn't have anything to do with the actually name of the variable. I know that perl must keep the name around though, because you can do evals that include the lexical variables.
    Even for package and global variables, I would imagine that it doesn't make much difference. The variable names would are probably prehashed, so the overhead of hashing a long variable name would only happen once at compile time.
Pathological example
by sleepingsquirrel (Hermit) on Jul 29, 2004 at 17:54 UTC
    Read (and heed) what the others above said about premature optimization. But here's what I get for one pathalogical exaple using large hash keys.
    greg@sparky:~/perl$ cat hashing_short #!/usr/bin/perl my $short="a"; my $long="This is a long hash key"x1000; my %h; $h{$short}++ for (1..1000000); greg@sparky:~/perl$ time hashing_short real 0m0.376s user 0m0.375s sys 0m0.001s greg@sparky:~/perl$ cat hashing_long #!/usr/bin/perl my $short="a"; my $long="This is a long hash key"x1000; my %h; $h{$long}++ for (1..1000000); greg@sparky:~/perl$ time hashing_long real 2m46.893s user 2m38.196s sys 0m0.278s


    -- All code is 100% tested and functional unless otherwise noted.

      By my calculation, your benchmark shows that each additional character in the hash key is costing you about 6.8 nanoseconds per lookup. That's probably the figure to be concentrating on in deciding how relevant this is.

      Hugo

Re: code execution speed and variable name length
by zentara (Archbishop) on Jul 29, 2004 at 17:44 UTC
    Here is the benchmark test I ran. There seems to be a non-negligible difference, but it isn't big enough to worry about unless you are trying some sort of highspeed realtime application. I didn't do any printouts, to be fair.
    #!/usr/bin/perl use warnings; use strict; use Benchmark; my %bighashname; my %b; timethese(10000, { hashbigname => sub { for(1..1000){ $bighashname{"bighashval$_"} = $_ } for(1..1000){ $bighashname{"bighashval$_"}++; } }, hashsmallname => sub { for(1..1000){ $b{"b$_"} = $_ } for(1..1000){ $b{"b$_"}++; } }, }); #Benchmark: timing 10000 iterations of hashbigname, hashsmallname... #hashbigname: 39 wallclock secs (39.27 usr + 0.00 sys = #39.27 CPU) @ + 254.65/s (n=10000) #hashsmallname: 35 wallclock secs (34.66 usr + 0.00 sys = #34.66 CPU) + @ 288.52/s (n=10000)

    I'm not really a human, but I play one on earth. flash japh
Re: code execution speed and variable name length
by hossman (Prior) on Jul 30, 2004 at 05:55 UTC

    for what i's worth...

    #!/usr/local/bin/perl use strict; use warnings; use Benchmark qw[ cmpthese timethese ]; package Benchmark; my @keys = ('s', 'm' x 10, 'l' x 100, 'h' x 1_000, 'r' x 100_000); sub test { my ($iters, $key) = @_; my %hash = (); # regardless of which key we use, build all the keys so the time # needed to clone a big string doesn't overshadow the time to clon +e # a small string. for (my $i = 0; $i < $iters; $i++) { $hash { (map { $_.$i } @keys)[$key] } = undef; } } my $many = 100; cmpthese(5*$many, { 'short' => sub { test($many, 0) }, 'medium' => sub { test($many, 1) }, 'long' => sub { test($many, 2) }, 'huge' => sub { test($many, 3) }, 'ridiculous' => sub { test($many, 4) }, }); __END__ laptop:~> monk.pl Benchmark: timing 500 iterations of huge, long, medium, ridiculous, sh +ort... laptop:~> monk.pl Benchmark: timing 500 iterations of huge, long, medium, ridiculous, sh +ort... huge: 31 wallclock secs (31.57 usr + 0.00 sys = 31.57 CPU) @ 15 +.84/s (n=500) long: 32 wallclock secs (30.39 usr + 0.03 sys = 30.42 CPU) @ 16 +.44/s (n=500) medium: 33 wallclock secs (30.03 usr + 0.01 sys = 30.04 CPU) @ 16 +.64/s (n=500) ridiculous: 187 wallclock secs (159.85 usr + 18.47 sys = 178.32 CPU) @ + 2.80/s (n=500) short: 30 wallclock secs (30.09 usr + 0.02 sys = 30.11 CPU) @ 16 +.61/s (n=500) Rate ridiculous huge long short medi +um ridiculous 2.80/s -- -82% -83% -83% -8 +3% huge 15.8/s 465% -- -4% -5% - +5% long 16.4/s 486% 4% -- -1% - +1% short 16.6/s 492% 5% 1% -- - +0% medium 16.6/s 494% 5% 1% 0% +--

    which seems to indicate that the key size can affect things, but only if you're dealing with seriously huge keys.

    Note:

    • zentara's benchmark doesn't take into account the fact that building up a big string takes longer then building up a short string .. hence i tried to make sure the only different between the tests was which key was added to the hash.
    • sleepingsquirrel's benchmark reuses two keys over and over (which does test the time spent hashing the keys, and is fair about the time spent building the string) so he doens't consider the added cost of storing lots of big keys. some people don't consider memory utilization a valid thing to consider when doing a Benchmark like this, but if it takes longer to execute access data because the data structure is really huge, that seems like a fair thing to consider.

      so he doens't consider the added cost of storing lots of big keys.

      Just wanted to add to this that keys in perl are reused. A key is stored only once, regardless of how many hashes it is used in. So while there is obviously an additional cost of using longer keys it doesnt mean that you will thousands of that key in memory if you have thousands of hashes that have that key within them. This also explains why hash keys are not normal scalar values (SV's).

      I believe that it was Gurusamy Sarathy that did the work whit the intention of making hash based objects more memory efficient.


      ---
      demerphq

        First they ignore you, then they laugh at you, then they fight you, then you win.
        -- Gandhi


Re: code execution speed and variable name length
by Forsaken (Friar) on Jul 31, 2004 at 07:44 UTC
    I think the other comments have already proven that the speed difference is negligible. I for one would just like to say that if for some reason someone else had to work with your code, I'm pretty confident they'd prefer the longer hash names :)
Re: code execution speed and variable name length
by TomDLux (Vicar) on Aug 04, 2004 at 02:53 UTC

    When you invoke a Perl function or operator, you have a function call overhead. I would expect processing time for a 20 character key vs a 2 character key to be small relative to function call overhead.

    Meaningful names are good, but don't fall into the Java trap of thinking that a $Variable_with_a_very_long_name is neccesarily more communicative than "$colour".

    If you are using multi-layered structures with long-ish names, it can clarify your code if you use aliases, especially if you are doing several operations in one vicinity of the structure:

    my $board = $game{'placedtiles'}{$currentuser} $board->{$row}{$col} = ... $board->{$row+1}{$col} =... $board->{$row-1}{$col} = ... $board->{$row}{$col+1} = ... $board->{$row}{$col-1} = ...

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://378376]
Approved by gellyfish
Front-paged by eserte
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (1)
As of 2022-09-30 19:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer my indexes to start at:




    Results (126 votes). Check out past polls.

    Notices?