in reply to updating an array of strings

A better approach than those suggested if you have a large array of information would be to make use of the splice function - This allows you to change an array element, O(1) execution, in place without iterating over the entire array, O(n) execution. For example:

my @array = ( 'foo', 'moo', 'baz' ); splice @array, 1, 1, 'bar';

The downside to this approach is that you will need to know the array position of the string which you are looking at modifying. If you do not know this index, then you would be better off exploring a loop or map construct as suggested and depending upon your requirements - Also of interest might be this node.

 

Replies are listed 'Best First'.
Re(2): updating an array of strings
by Arien (Pilgrim) on Aug 26, 2002 at 06:40 UTC

    splice is not what you are looking for. A simple assignment is the clearest and most efficient way to update the value of an array element with a known index.

    my @array = qw(foo moo baz); $array[1] = 'bar';

    — Arien

      Perl never ceases to amaze me. After seeing Arien's point I wondered just how much slower it was to build a stack frame, do the assignment and knock the stack frame down again.

      I've seen various references to "the overhead of calling a sub" and have been guilty of not sub-ing when I should have because of it. I needn't have worried. I was expecting a vastly higher overhead than this demonstrates!

      #!perl -w use strict; use Benchmark; my @ary = 0 .. 100; Benchmark::cmpthese ( 10_000_000, { 'assignment' => '$ary[1] = -1;', 'splice' => 'splice @ary, 1, 1, -1;' } ); __END__ # Output C:\test>192779 Benchmark: timing 10000000 iterations of assignment, splice... assignment: 21 wallclock secs (19.65 usr + 0.00 sys = 19.65 CPU) @ 50 +8931.75/s (n=10000000) splice: 56 wallclock secs (57.13 usr + 0.01 sys = 57.14 CPU) @ 17 +4999.56/s (n=10000000) Rate splice assignment splice 175000/s -- -66% assignment 508932/s 191% --

      What's this about a "crooked mitre"? I'm good at woodwork!

        Umm, neither of these calls a subroutine. splice is a list operator, not a sub -- no call stack need be generated, because no perl code is being called.

        #!perl -w use strict; use Benchmark; my @ary = 0 .. 100; sub test { $a++; } Benchmark::cmpthese ( -1, { direct => sub {$a++}, sub => sub {test} } ); __END__ Benchmark: running direct, sub, each for at least 1 CPU seconds... direct: 1 wallclock secs ( 1.48 usr + 0.00 sys = 1.48 CPU) @ 34 +6460.81/s (n=512762) sub: 1 wallclock secs ( 1.00 usr + 0.00 sys = 1.00 CPU) @ 13 +7843.00/s (n=137843) Rate sub direct sub 137843/s -- -60% direct 346461/s 151% --


        Confession: It does an Immortal Body good.