in reply to Can this script be Optimized?

There's a number of improvements you could make. Here's a (not necessarily complete) list:

I took your original spec and produced the following script. While I kept to the spec, I made no any attempt to reproduce any parts of your script.

#!/usr/bin/env perl -l use strict; use warnings; use List::Util qw{max}; my %Hash = ( "A" => ["HYU"], "B" => ["TU6"], "C" => [ "11", "09", "88", "2" ], "D" => [ "01", "11" ] ); my @keys = sort keys %Hash; print join ",\t" => @keys; { no warnings 'uninitialized'; for my $i (0 .. max map { $#{$Hash{$_}} } @keys) { print join "\t" => map { $Hash{$_}[$i] } @keys; } }

Output:

A, B, C, D HYU TU6 11 01 09 11 88 2

Using tabs for the output worked in this instance; however, with other data, columns may be out of alignment. Also, tab widths can vary; so what looks fine here may be misaligned elsewhere. Consider using printf to format your output.

Also have a read of "Perl Performance and Optimization Techniques" for more tips you can use in your other scripts.

-- Ken

Replies are listed 'Best First'.
Re^2: Can this script be Optimized?
by tobyink (Canon) on May 01, 2014 at 08:00 UTC

    "As far as I know, all of the functions provided by that module are implemented in C, so you also get a performance bonus."

    Indeed, they are. List::Util also happens to make very efficient use of Perl's API (e.g. using multicall), allowing its functions to perform at speeds approaching Perl's built-in list operators (grep, map, sort).

    "See also: List::MoreUtils"

    This is also written in C (and also makes use of multicall), but has a fallback Perl implementation allowing it to be installed on machines lacking a C compiler.

    If a function exists in both List::Util and List::MoreUtils (and because recent List::Util releases have been adding new functions, the overlap between them is growing), then prefer the List::Util one because it will be guaranteed to be implemented in C.

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

      Thanks for the feedback.

      I had seen the C and pure-Perl implementation information in List::MoreUtils [from CPAN]; however, the List::Util [from perldoc.perl.org] documentation made no mention of this: hence the "As far as I know" qualifier.

      I was a little surprised when you mentioned there was an overlap between these two modules as I wasn't aware of this. I did a little investigation and found:

      http://perldoc.perl.org/List/Util.html

      Indicates Perl v5.18.2 and only shows these functions: first max maxstr min minstr reduce shuffle sum. It does show any, all, et al, which currently exist in List::MoreUtils, as suggested additions which haven't been included. (I couldn't find any mention of a module version number.)

      http://search.cpan.org/~pevans/Scalar-List-Utils-1.38/lib/List/Util.pm

      This does show any, all, et al as being included.

      $ perldoc List::Util

      This appears to be the same doco as the CPAN version. Checking my versions: List::Util 1.38 and Perl 5.18.1

      I have, up until now, used the perldoc.perl.org documentation for all builtin modules. It's clear that this is out-of-date for List::Util (i.e. it's not the POD that ships with 5.18.2); unfortunately, this leave me wondering what other parts of its doco aren't up-to-date.

      -- Ken

        Beginning with List::Util 1.28, List::Util added a great deal of new functions. However, the version of List::Util included in the Perl 5.18.x releases is 1.27. (And perldoc.perl.org only includes documentation for modules bundled with stable releases of Perl.)

        The new functions are:

        • Added in 1.28: pairgrep, pairmap, pairs, pairkeys, and pairvalues.
        • Added in 1.30: pairfirst.
        • Added in 1.33: any, all, none, and notall. ← these are the ones which overlap with List::MoreUtils
        • Added in 1.35: product.

        I don't know what version of List::Util will be bundled with Perl 5.20.0, but it's likely to be at least 1.38. Of course, you don't need to wait for Perl 5.20.0 to use these functions; List::Util 1.38 is already on CPAN.

        use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
Re^2: Can this script be Optimized?
by RonW (Parson) on May 01, 2014 at 16:40 UTC

    In the interest of education, map is a "feature enhanced" version of for.

    map { expr; } @array; is equivalent to:

    for (@array) { push @newarray, expr; }

    Presumably, expr uses $_ either implicitly or explicitly.

    Similarly, grep { expr; } @array; is equivalent to:

    for (@array) { push @newaray, $_ if expr; }

      Actually, I'd say a closer equivalency would be

      my @newarray = map { expr } @array;

      and

      my @newarray; for (@array) { push @newarray, expr; }

      Or, conversely

      map { expr } @array;

      and

      for (@array) { expr; }

      or

      expr for @array;

      Anyway, as that was a reply to my post, were you suggesting I replace a map with a for, or vice versa? Or, perhaps, something else?

      -- Ken

        No, just pointing out that map (and grep) are basically equivalent to for. But like many other features of Perl, they can make some things easier to code and easier to read.

        Your point is correct. One additional detail is that a new array (actually list) is always created.

        So, it would really be more like:

        { my $newarray; for (@array) { push @newarray, expr; } @newarray; }