note smls <p>Here are some attempts at improving performance, compared to the solutions already posted <i>(of which BrowserUK's <a href="http://www.perlmonks.org/?node_id=171588">recursive solution</a> was the fastest)</i>:</p> <h3>Branching solution</h3> <p>A trivial (but non-elegant) way to gain performance is to directly implement the nested loops for a few (presumably common) values of <code>n</code>, using if/elsif/else to branch between them, and only fall back to the general-case <a href="http://www.perlmonks.org/?node_id=171588">recursive implementation</a> for higher values of <code>n</code>:</p> <code> sub multi_foreach(&@) { my \$code = shift; if (@_ == 1) { for my \$i (@{ shift() }) { \$code->( \$i ); } } elsif (@_ == 2) { my (\$a0, \$a1) = @_; for my \$i0 (@\$a0) { for my \$i1 (@\$a1) { \$code->( \$i0, \$i1 ); } } } elsif (@_ > 2) { my (\$a0, \$a1, \$a2, @rest) = @_; for my \$i0 (@\$a0) { for my \$i1 (@\$a1) { for my \$i2 (@\$a2) { if (@rest) { &multi_foreach_recursive( \$code, scalar @rest, @rest, \$i0, \$i1, \$i2 ); } else { \$code->( \$i0, \$i1, \$i2 ); } } } } } } multi_foreach { say join ' ', @_ } \( @a, @b, @c ); </code> <h3><code>eval</code> solution</h3> <p>The logical generalization of the branching solution, would be to dynamically generate the nested <code>foreach</code> loops for arbitrary levels of nesting. This incurs an overhead for code-generation each time the algorithm is called <i>(PS: caching could help)</i>, but once generated the actual looping code will run very fast. Thus this solution tends to be slower than the recursive solution for <b>small</b> inputs, but faster for <b>large</b> inputs (i.e. many big arrays):</p> <code> sub multi_foreach(&@) { my \$code = shift; my (\$head, \$inside, \$tail) = ('', '\$code->(', ')'); foreach (0..\$#_) { \$head .= "for my \\$i\$_ (\@{\\$_[\$_]}) { "; \$inside .= "\\$i\$_, "; \$tail .= ' }'; } eval( \$head . \$inside . \$tail ); } multi_foreach { say join ' ', @_ } \( @a, @b, @c ); </code> 1064607 1064607