{"id":597,"date":"2015-09-22T23:46:58","date_gmt":"2015-09-22T22:46:58","guid":{"rendered":"http:\/\/www.muratyaman.co.uk\/wp\/?p=597"},"modified":"2020-04-01T12:47:06","modified_gmt":"2020-04-01T11:47:06","slug":"php-the-cost-of-a-million-objects-on-function-calls","status":"publish","type":"post","link":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/2015\/09\/php-the-cost-of-a-million-objects-on-function-calls\/","title":{"rendered":"PHP: The cost of a million objects on function calls"},"content":{"rendered":"<p>Especially, if you are a start-up, all it takes is a fine combination of:<\/p>\n<ul>\n<li>a bad coder (with an arrogant attitude of &#8220;code first + optimize later&#8221;)<\/li>\n<li>and 1000 simultaneous requests<\/li>\n<\/ul>\n<p>to bring each of your servers to its &#8220;knees&#8221;.<\/p>\n<p>On <a href=\"\/wp\/index.php\/2015\/09\/php-memory-usage-the-cost-of-a-million-objects\/\">part 1<\/a>, I&#8217;ve mentioned the cost of a million items when we are using arrays in PHP.<\/p>\n<p>In this part, I want to highlight related features when we are passing such arrays to functions.<\/p>\n<ul>\n<li>version 1: array of arrays: passed by value<\/li>\n<li>version 2: array of arrays: passed by reference<\/li>\n<li>version 3a: array of objects: passed by value and reassigned objects in function<\/li>\n<li>version 3b: array of objects: passed by value without reassigned objects<\/li>\n<li>version 4: array of objects: passed by reference<\/li>\n<\/ul>\n<p>Let&#8217;s see the first version of the code:<\/p>\n<p><code lang=\"php\"><br \/>\n<?php\n\n$t0 = microtime(true);\n\nfunction myProcess(array $array)\n{\n    foreach($array as $i => $row) {<br \/>\n        $row['a'] = strrev($row['a']);<br \/>\n\t\t$array[$i] = $row;<br \/>\n    }<\/p>\n<p>    return $array;<br \/>\n}<\/p>\n<p>$arr = [];<\/p>\n<p>$L = 1000000;<br \/>\n$S = 'abcdefghijklmnopqrstuvwxyz';<br \/>\nmt_srand();<br \/>\nfor($i = 1; $i <= $L; $i++) {\n    $row = [\n        'a' => str_shuffle($S),\/\/string<br \/>\n        'b' => mt_rand(0, $L) \/ mt_rand(1, $L),\/\/float<br \/>\n        'c' => mt_rand(-1000, 1000),\/\/int<br \/>\n    ];<br \/>\n    $arr[] = $row;<br \/>\n}<\/p>\n<p>echo '1 item 0 -> a:' . ($arr[0]['a']) . PHP_EOL;<br \/>\n$arr2 = myProcess($arr);<br \/>\necho '1 item 0 -> a:' . ($arr[0]['a']) . PHP_EOL;<br \/>\necho '2 item 0 -> a:' . ($arr2[0]['a']) . PHP_EOL;<\/p>\n<p>$t1 = microtime(true);<br \/>\n$mem = memory_get_usage(true);<\/p>\n<p>echo 'Array of ' . number_format($L) . ' arrays.' . PHP_EOL;<br \/>\necho 'Time taken: ' . number_format($t1 - $t0, 3) . 'ms.' . PHP_EOL;<br \/>\necho 'Memory usage: ' . number_format($mem \/ 1024, 1) . 'KB.' . PHP_EOL;<br \/>\n?><br \/>\n<\/code><\/p>\n<p>I&#8217;ve got the best results when I used the version 4:<\/p>\n<p><code lang=\"php\"><br \/>\n<?php\n\n$t0 = microtime(true);\n\nfunction myProcess(array &#038; $array)\n{\n\tforeach($array as $i => $row) {<br \/>\n        $row->a = strrev($row->a);<br \/>\n\t\t\/\/$array[$i] = $row; \/\/no need because objects in arrays have references<br \/>\n    }<\/p>\n<p>    \/\/return $array; \/\/no need to return, because we are modifying the array given by reference<br \/>\n}<\/p>\n<p>class myClass<br \/>\n{<br \/>\n    public $a;<br \/>\n    public $b;<br \/>\n    public $c;<br \/>\n    function __construct($a, $b, $c)<br \/>\n    {<br \/>\n        $this->a = $a;<br \/>\n        $this->b = $b;<br \/>\n        $this->c = $c;<br \/>\n    }<br \/>\n}<\/p>\n<p>$arr = [];<\/p>\n<p>$L = 1000000;<br \/>\n$S = 'abcdefghijklmnopqrstuvwxyz';<br \/>\nmt_srand();<br \/>\nfor($i = 1; $i <= $L; $i++) {\n    $row = new myClass(\n        str_shuffle($S),\/\/string\n        mt_rand(0, $L) \/ mt_rand(1, $L),\/\/float\n        mt_rand(-1000, 1000)\n    );\n    $arr[] = $row;\n}\n\necho '1 object 0 -> a:' . ($arr[0]->a) . PHP_EOL;<br \/>\nmyProcess($arr);<br \/>\necho '1 object 0 -> a:' . ($arr[0]->a) . PHP_EOL;<\/p>\n<p>$t1 = microtime(true);<br \/>\n$mem = memory_get_usage(true);<\/p>\n<p>echo 'Array of ' . number_format($L) . ' custom objects.' . PHP_EOL;<br \/>\necho 'Time taken: ' . number_format($t1 - $t0, 3) . 'ms.' . PHP_EOL;<br \/>\necho 'Memory usage: ' . number_format($mem \/ 1024, 1) . 'KB.' . PHP_EOL;<br \/>\n?><br \/>\n<\/code><\/p>\n<p>You can see all the files on <a href=\"https:\/\/github.com\/muratyaman\/php-tips\">my github project<\/a>.<\/p>\n<p>The surprising cases for me were version 3a and version 3b. Simply, I didn&#8217;t expect a difference of 50MB because I thought they are effectively doing the same job.<\/p>\n<p>And here is the chart to compare them:<\/p>\n<p><a href=\"http:\/\/www.muratyaman.co.uk\/wp\/wp-content\/uploads\/2015\/09\/php-memory-usage-chart-on-function-calls.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.muratyaman.co.uk\/wp\/wp-content\/uploads\/2015\/09\/php-memory-usage-chart-on-function-calls-300x198.jpg\" alt=\"php-memory-usage-chart-on-function-calls\" width=\"300\" height=\"198\" class=\"aligncenter size-medium wp-image-598\" srcset=\"https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2015\/09\/php-memory-usage-chart-on-function-calls-300x198.jpg 300w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2015\/09\/php-memory-usage-chart-on-function-calls.jpg 940w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Note: This time, I didn&#8217;t use the logarithmic scale.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Especially, if you are a start-up, all it takes is a fine combination of &#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[194,26],"class_list":["post-597","post","type-post","status-publish","format-standard","hentry","category-technology","tag-performance","tag-php"],"_links":{"self":[{"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/597","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=597"}],"version-history":[{"count":5,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/597\/revisions"}],"predecessor-version":[{"id":965,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/597\/revisions\/965"}],"wp:attachment":[{"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=597"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=597"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=597"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}