Posts

Showing posts with the label memory usage

Runtime vs. memory usage

Oftentimes, better runtime can result in higher memory usage. Here is an example to create some strings to test bulk inserts on Redis: $cmd = ""; $start = microtime(true); for ($i=0; $i<1000000; $i+=2) $cmd .= "SET entity:".$i.":key value_".($i+1)."\r\n"; echo number_format(microtime(true)-$start, 1)."s\n"; // 0.7s echo number_format(memory_get_usage(true)/1048576, 1)." MB\n"; // 17.5 MB echo number_format(memory_get_peak_usage(true)/1048576, 1)." MB\n"; // 17.5 MB $cmd = ""; $start = microtime(true); $cmd = vsprintf(str_repeat("SET entity:%d:key value_%d\r\n", 500000), range(0,1000000)); echo number_format(microtime(true)-$start, 1)."s\n"; // 0.4s echo number_format(memory_get_usage(true)/1048576, 1)." MB\n"; // 30.8 MB echo number_format(memory_get_peak_usage(true)/1048576, 1)." MB\n"; // 128.5 MB (PHP 5.4.5, 2.5 GHz, win64) We see that the same result can be c...

How to write a really small and fast controller with PHP (update: benchmark Slim, Silex, Zend Framework, Symfony2)

To handle a lot of traffic, we need a fast controller with very little memory overhead. First, we implement a dynamic controller . The design is based on the micro frameworks Slim and Silex . The first example maps the URL "http://server/index.php/blog/2012/03/02" to a function with the parameters $year, $month and $day: // index.php, handle /blog/2012/03/02 $app = new App(); $app->get('/blog/:year/:month/:day', function($year, $month, $day) { printf('%d-%02d-%02d', $year, $month, $day); }); Our controller is a class named App and uses the get() function to map a GET request. Parameters mapped to the function are marked with a colon. Optional parameters are written inside brackets. Here is an example: // handle /blog, /blog/2012, /blog/2012/03 and /blog/2012/03/02 $app = new App(); $app->get('/blog(/:year(/:month(/:day)))', function($year=2012, $month=1, $day=1) { printf('%d-%02d-%02d', $year, $month, $day); }); Instead of ...

How to implement i18n without performance overhead

i18n is always difficult to implement and costs a lot performance. Normally, implementations use gettext() or a custom t()-function to translate a string. t() searches a INI or XML file for a translation key and returns the value. For example t('setting', 'de'), gives the German translation 'Einstellung'. Typical optimizations use associative arrays (hashmaps) loaded into APC or Memcached. This requires a lot of memory for the array and produces a lot of cpu cycles for calling t() all the time. So the question is, can we do this better? Yes! We use a just-in-time compiler for our PHP files and write the compiled PHP files to disk, so APC can cache them like regular PHP files. An example PHP class looks like this: // example.php <?php class example { public function now() { return '{t}Hello World, now it is:{/t} '.date('{t}m/d/Y g:i a{/t}'); } } The "{t}" and "{/t}" patterns serve as opening and closing tags indi...

Things you should not do in PHP (update: references)

Here is a list of things you should not do in PHP. Most of the stuff is pretty obvious, but over the years I've seen a lot of them. In most cases, these problems remain hidden until data grows above 10000 entries. So on a development system, things are always fast and there are no problems with memory limits :-) Suppose we have a table with 100k entries: $db->query('create table stats (c1 int(11) primary key, c2 varchar(255))'); $db->query('begin'); for ($i=0; $i<100000; $i++) { $db->query('insert into stats values ('.$i.','.($i*2).')'); } $db->query('commit'); Populate a big array instead of streaming results: $result = $db->query('select * from stats'); $array = $result->fetch_all(); // 35M // or while ($row = $result->fetch_assoc()) $array[] = $row; // 35M // or while ($row = $result->fetch_array()) $array[] = $row; // 44.5M // process $array ... // instead of: while ($row = $result->fetch...

PHP memory consumption with Arrays and Objects (update: generators)

Lessons learned: objects need more memory than arrays (+ 2-10 percent) comparing 32bit to 64bit systems, memory consumption increases by 100-230 percent if array values are numeric, don't save them as strings! saving 1M integers takes 200M of memory with PHP on a 64bit plattform (increase by factor 25) using SplFixedArray can reduce memory usage by 20-130 percent avoid big Arrays and Objects in PHP whenever possible (don't use file('big_file') or explode("\n", file_get_contents('big_file')), etc.) use streams whenever possible (fopen, fsockopen, etc.) use generators when available with PHP 5.5 ( RFC ) If you need to save memory temporarily in your script, you can stringify your array (increasing cpu usage and runtime): $a = array(); for ($i=0; $i $a[] = $i; } $a = implode(',', $a); // or $a = json_encode($a); echo number_format(memory_get_usage(true)/1048576, 2)."\n"; // 8.0 M (64bit), 7.5 M (32bit) Here is a small script to sh...