{"id":390,"date":"2010-02-05T17:48:08","date_gmt":"2010-02-06T00:48:08","guid":{"rendered":"http:\/\/www.evardsson.com\/blog\/?p=390"},"modified":"2011-02-21T15:31:18","modified_gmt":"2011-02-21T22:31:18","slug":"comparing-php-array_shift-to-array_pop","status":"publish","type":"post","link":"https:\/\/www.evardsson.com\/blog\/2010\/02\/05\/comparing-php-array_shift-to-array_pop\/","title":{"rendered":"Comparing PHP array_shift to array_pop"},"content":{"rendered":"<p>I noticed a note in the PHP documentation about speed differences between array_shift() (pulling the first element off the array) and array_reverse() followed by array_pop() (resulting in the same data, but got to by pulling the last element off the array).<\/p>\n<p>Since I was working on some code to convert URL pieces to program arguments (like turning \/admin\/users\/1\/edit into section=admin, module=users, id=1, action=edit &#8211; stuff we tend to do every day) I thought I would take a look at the speed differences since I have always used array_shift() for this (after turning the string into an array via explode()).<\/p>\n<p>My initial tests showed that array_shift was much faster than array_reverse followed by array_pop, and I wondered why someone would say that in the first place. But then I thought about it for a bit. When using array_shift the entire remaining array has to be re-indexed every call. For a very short array (like the one I was using) this is negligible. When you start looking at much larger arrays, however, this overhead adds up quickly.<\/p>\n<p>To find out roughly where the break-even point on these two methods lie I whipped up a quick script to run with arrays sized from 10^1 values up to 10^5 values. What I found is that at less than 100 values you are not really gaining much (if anything) by using array_reverse and array_pop versus array_shift. Once you get to the 1000 value array size, however, the differences really add up (as you can see in the logarithmic scaling of the chart below).<\/p>\n<p><a class=\"tt-flickr tt-flickr-Large\" title=\"shift_vs_pop.jpg\" href=\"http:\/\/www.flickr.com\/photos\/evardsson\/4333796938\/\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"http:\/\/farm5.static.flickr.com\/4015\/4333796938_aa76fc6940_o.jpg\" alt=\"shift_vs_pop.jpg\" width=\"647\" height=\"619\" \/><\/a><\/p>\n<p>The code I used to generate the numbers (which are shown in the chart as averages over 3 runs, rounded to the nearest millionth of a second) is:<\/p>\n<pre class=\"brush: php\">\r\n&lt;?php\r\n$counts = array(10,100,1000,10000,100000);\r\nforeach ($counts as $len)\r\n{\r\n\t$m2 = $m1 = array();\r\n\t$x = 1;\r\n\twhile ($x <= $len)\r\n\t{\r\n\t\t$m2[] = $m1[] = $x;\r\n\t\t$x++;\r\n\t}\r\n\techo \"Timing with array_shift() for $len items\\n\";\r\n\techo \"000000\";\r\n\t$s1 = microtime(true);\r\n\twhile (!empty($m1))\r\n\t{\r\n\t\t$tmp = array_shift($m1);\r\n\t\tif ($tmp % 10 == 0)\r\n\t\t{\r\n\t\t\techo chr(8),chr(8),chr(8),chr(8),chr(8),chr(8);\r\n\t\t\techo str_pad(''.$tmp,6,'0',STR_PAD_LEFT);\r\n\t\t}\r\n\t}\r\n\t$s2 = microtime(true);\r\n\techo \"\\nTook \",$s2 - $s1,\" seconds\\n\";\r\n\t\r\n\techo \"Timing with array_reverse and array_pop() for $len items\\n\";\r\n\t$s1 = microtime(true);\r\n\t$m2 = array_reverse($m2);\r\n\twhile (!empty($m2))\r\n\t{\r\n\t\t$tmp = array_pop($m2);\r\n\t\tif ($tmp % 10 == 0)\r\n\t\t{\r\n\t\t\techo chr(8),chr(8),chr(8),chr(8),chr(8),chr(8);\r\n\t\t\techo str_pad(''.$tmp,6,'0',STR_PAD_LEFT);\r\n\t\t}\r\n\t}\r\n\t$s2 = microtime(true);\r\n\techo \"\\nTook \",$s2 - $s1,\" seconds\\n\";\r\n\techo \"\\n\";\r\n}\r\n?&gt;\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I noticed a note in the PHP documentation about speed differences between array_shift() (pulling the first element off the array) and array_reverse() followed by array_pop() (resulting in the same data, but got to by pulling &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[11,33],"tags":[148,170],"class_list":["post-390","post","type-post","status-publish","format-standard","hentry","category-development","category-php","tag-development","tag-php"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pxT7i-6i","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.evardsson.com\/blog\/wp-json\/wp\/v2\/posts\/390","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.evardsson.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.evardsson.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.evardsson.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.evardsson.com\/blog\/wp-json\/wp\/v2\/comments?post=390"}],"version-history":[{"count":3,"href":"https:\/\/www.evardsson.com\/blog\/wp-json\/wp\/v2\/posts\/390\/revisions"}],"predecessor-version":[{"id":509,"href":"https:\/\/www.evardsson.com\/blog\/wp-json\/wp\/v2\/posts\/390\/revisions\/509"}],"wp:attachment":[{"href":"https:\/\/www.evardsson.com\/blog\/wp-json\/wp\/v2\/media?parent=390"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.evardsson.com\/blog\/wp-json\/wp\/v2\/categories?post=390"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.evardsson.com\/blog\/wp-json\/wp\/v2\/tags?post=390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}