BrowserUk operates in an environment in which it is vital to squeeze every last, living computron from any processor, algorithm or function with which he deals, so I am not inclined to dispute his assertion that indirect access is "vastly less efficient".
The "vastly less efficient" was in response *only* to 7stud's suggested: my @ydata = @{shift()};.
Duplicating multiple, multi-dimensional arrays (in the case of mat mult), in order to achieve the same, non-indirected notation as you get with aliasing is "vastly less efficient".
Taking that quote, out of that context, is a strawman.
I would say that the (untested) way I have re-written mmMxM() below is, to my taste, at least as clear as the original.
For this simple example, it's not horribly more complex I grant you. But that is the tip of the iceberg.
Rather than this hard-coded sized, square-matrix multiply, let's take the more general form of MxN MatMult:
sub mmMxN {
our( @M, @N );
local( *M, *N ) = @_;
die "Incompatible matrix dimensions" unless @M == @{ $N[0] };
my @C = map[ (0) x @M ], 0 .. $#{ $N[ 0 ] };
for my $i ( 0 .. $#M ) {
for my $j ( 0 .. $#{ $N[0] } ) {
$C[ $i ][ $j ] += $M[ $i ][ $_ ] * $N[ $_ ][ $j] for 0 ..
+ $#N;
}
}
return \@C;
}
Now the indirect notation would take a somewhat higher cost on clarity.
Now consider that this is a method within an OO module, and the matrices in question are named instance variables in the object: sub mmMxN {
my $self = shift;
die "Incompatible matrix dimensions" unless @{ $self->{M} } == @{
+$self->{N}->[0] };
$self->{R} = map[ (0) x @{ $self->{M} } ], 0 .. $#{ $self->{N}->[
+0 ] };
for my $i ( 0 .. $#{ $self->{M} } ) {
for my $j ( 0 .. $#{ $self->{N}->[0] } ) {
$self->{R}->[$i]->[$j] += $self->{M}->[$i]->[$_] * $self->
+{N}->[$_]->[$j] for 0 .. $#{ $self->{N} };
}
}
return $self->{R};
}
Yes, you can use temporaries for the array refs; and I've also exaggerated the syntax problem for effect, but even without that, this is preferable: sub mmMxN {
our ( @M, @N );
my $self = shift;
local( *M, *N ) = @{ $self }{ M, N };
die "Incompatible matrix dimensions" unless @{ $M } == @{ $N[0] };
my @R = map[ (0) x @M ], 0 .. $#N[ 0 ];
for my $i ( 0 .. $#M ) {
for my $j ( 0 .. $#{ $N[0] } ) {
$R[$i][$j] += $M[$i][$_] * $N[$_][$j] for 0 .. $#N;
}
}
$self->{R} = \@R;
}
(IMO anyway :)
PS. See also The seven good uses for local.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
|