Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^3: aliasing arrays using typeglob under strict

by AnomalousMonk (Abbot)
on Feb 08, 2013 at 16:54 UTC ( #1017861=note: print w/ replies, xml ) Need Help??


in reply to Re^2: aliasing arrays using typeglob under strict
in thread aliasing arrays using typeglob under strict

Try re-writing this without aliasing and it will either be much less clear syntactically; or vastly less efficient...

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".

I would argue with his assertion about clarity. This, of course, is very much a matter of personal taste; I'm not aware of any widely accepted metric for benchmarking 'clarity' – or even for defining its meaning! I would say that the (untested) way I have re-written  mmMxM() below is, to my taste, at least as clear as the original. (Again, all issues of performance are entirely neglected. And I don't understand what this thing is doing in the first place... some kind of matrix multiply?)

use constant N => 3; sub mmMxM { my ($ar_A, # ref. to array of ... $ar_B, # ref. to array of ... ) = @_; my @c = map [ map 0, 0..N ], 0..N; # AoA of zeros for my $i (0..N) { for my $j (0..N) { $c[$i][$j] += $ar_A->[$i][$_] * $ar_B->[$_][$j] for 0..N; } } return \@c; }

I have, believe me, the utmost respect for BrowserUk, a most subtle and puissant (that's puissant, not pissant!) monk whose programming boots I am not fit to lick clean, but I felt compelled to offer my USD0.02 on the subject of clarity.


Comment on Re^3: aliasing arrays using typeglob under strict
Select or Download Code
Re^4: aliasing arrays using typeglob under strict
by BrowserUk (Pope) on Feb 08, 2013 at 18:44 UTC
    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.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1017861]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (9)
As of 2014-09-16 19:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (45 votes), past polls