It's pretty easy just to assume that "it" is so. "It" may of course be any of many things, but in this case "it" is that "push and pop are obviously faster than unshift and shift". Clearly push and pop work at the growable end of the array so obviously there is an efficiency advantage. I was curious to see how much faster the push/pop pair were than the unshift/shift pair. The answer may come as something of a surprise - it did to me!

use strict; use warnings; use Benchmark qw(cmpthese); my @template = (1) x 200; cmpthese ( -10, { 'push pop', sub {pushPop ();}, 'push shift', sub {pushShift ();}, 'unshift pop', sub {unshiftPop ();}, 'unshift shift', sub {unshiftShift ();}, } ); sub pushPop { my @from = @template; my @to; for (0..100) { push @to, pop @from for @from; push @from, pop @to for @to; } } sub pushShift { my @from = @template; my @to; for (0..100) { push @to, shift @from for @from; push @from, shift @to for @to; } } sub unshiftPop { my @from = @template; my @to; for (0..100) { unshift @to, pop @from for @from; unshift @from, pop @to for @to; } } sub unshiftShift { my @from = @template; my @to; for (0..100) { unshift @to, shift @from for @from; unshift @from, shift @to for @to; } }
Rate unshift shift push pop unshift pop push +shift unshift shift 129/s -- -0% -4% + -6% push pop 129/s 0% -- -3% + -6% unshift pop 134/s 4% 3% -- + -2% push shift 137/s 6% 6% 2% + --

There are two big surprises here, at least for me:

Every now and then a problem comes up that could be solved using either of the stack pairs. In the past I would always choose push/pop. Now I'm happier thinking about the best expression of the problem and not being distracted by assumed efficiency issues.

Even more interesting though is the queue result which was quite unexpected. Note though that the fastest pair was push/shift. After a little contemplation this is not quite so surprising. After all shift is often used to pull arguments out of the list passed to a sub and push is often used to tack elements on to the end of a list. These are used much more than pop and unshift so it makes sense that there is some optimisation for them. Obvious after the benchmark anyway. :)


Perl is Huffman encoded by design.

In reply to To push and pop or not to push and pop? by GrandFather

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.