http://qs321.pair.com?node_id=145533

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

In the application I am working on the environment must is (must be) populated with many variables. The application utilizes several local modules. Out of curiosity is there a performance (or other) differences between utilizing the $ENV{'FOO') or a scoped $var ?

coreolyn

Replies are listed 'Best First'.
(crazyinsomniac: %ENV equals overhead) Re: $ENV {'FOO'} $foo
by crazyinsomniac (Prior) on Feb 14, 2002 at 23:14 UTC
Re: $ENV {'FOO'} $foo
by wog (Curate) on Feb 14, 2002 at 23:57 UTC

    On most systems there will be a signifigant performance overhead from using %ENV rather then a "normal" variable. %ENV access a system dependent table, which is typically not designed for efficient access. (On UNIX, for example, the environment table is (usually, at least) stored as an unordered, C-style, null-terminated array of strings in the format "KEY=VALUE". Searching through this to find an element is not very efficient, obviously.) Unless you need to interface with C code that uses environment variables or want to pass things to your child processes or recieve things from parent processes, you probably shouldn't use %ENV.

Re: $ENV {'FOO'} $foo
by steves (Curate) on Feb 15, 2002 at 01:04 UTC

    There are two other considerations here that have nothing to do with speed and which contradict one another:

    • Do you really want your entire program to know that a certain setting is picked up from the environment? I usually view the environment as a configuration type interface: Load from it once only so I can change the source of a setting later if needed.
    • On the opposite side: If a value is known to be environmental, can any other parts of the program (e.g., used packages) set it? If so, then taking it once may have the wrong effect if someone tries to set it later, expecting that later setting to have some effect.

    These are mostly maintenance/large program considerations. So if this is a simple script, you can probably disregard them as factors. For large systems I tend to take the approach that hides data sources and manipulations the most since it makes longer term changes easier.

Re: $ENV {'FOO'} $foo
by Rich36 (Chaplain) on Feb 14, 2002 at 20:30 UTC
    I tested this idea out with this code.
    #!/usr/bin/perl -w use strict; use Benchmark; { # Start the benchmark my $start = new Benchmark; for(1..1000) { print qq($ENV{PATH}\n); } # End the program and return the Benchmark time my $end = new Benchmark; print "Processing time was...\n"; print timestr(timediff($end, $start)) . "\n"; } sleep 10; { my $foo = $ENV{PATH}; # Start the benchmark my $start = new Benchmark; for(1..1000) { print qq($foo\n); } # End the program and return the Benchmark time my $end = new Benchmark; print "Processing time was...\n"; print timestr(timediff($end, $start)) . "\n"; }
    Using 1000 iterations in the loop, the results I got were...
    Loop using $ENV{PATH}: 12 wallclock secs ( 0.13 usr + 0.15 sys = 0.2 +8 CPU) Loop using $foo: 11 wallclock secs ( 0.07 usr + 0.05 sys = 0.12 CPU)
    So it looks like there was some performance gain in that example using the stored var instead of directly accessing the hash value. I would guess that the second loop was faster because the application didn't have to search through a hash for the value, but someone else who has a better idea of the internal workings of Perl might be able to tell you more.
    Personally, if I'm using a lot of environment variables, I like to assign them to variable names so I can assign them a name I want and not have to worry about typing $ENV{FOO} again and again.
    Rich36
    There's more than one way to screw it up...

Re: $ENV {'FOO'} $foo
by rinceWind (Monsignor) on Feb 15, 2002 at 00:27 UTC

    It definitely depends on the OS platform on which you are running, as this is where %ENV happens. It is behaving as a tied hash, hence slower than a real hash as extra bits of code are being called.

    A lot depends on the implementation, and this may be quirky due to how the operating system handles environments.

    See the vmsperl@perl.org mailing list archives for some examples of this.

Re: $ENV {'FOO'} $foo
by coreolyn (Parson) on Feb 15, 2002 at 01:22 UTC

    Thanks all for the input it is appreciated. (especially as the question was so hastily/poorly written -- sorry 'bout that)

    This is a heavily used set of scripts by diverse teams. While performance is not critical I like to do what I can to stay streamlined. It's dependence on $ENV has to do with its evolution from a family of ksh scripts that utilize about 30 environmental variables to control their functionality. I'm waying the pro's and cons of 'speed' to the production floor vrs code cleanliness and performance.

    Me thinks I should just wipe 'em all out though that will definately add more to the time curve.

    Thanks again,

    coreolyn