Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP array performance

I'm testing an algorithm for 2d bin packing and I've chosen PHP to mock it up as it's my bread-and-butter language nowadays.

As you can see on http://themworks.com/pack_v0.2/oopack.php?ol=1 it works pretty well, but you need to wait around 10-20 seconds for 100 rectangles to pack. For some hard to handle sets it would hit the php's 30s runtime limit.

I did some profiling and it shows that most of the time my script goes through different parts of a small 2d array with 0's and 1's in it. It either checks if certain cell equals to 0/1 or sets it to 0/1. It can do such operations million times and each times it takes few microseconds.

I guess I could use an array of booleans in a statically typed language and things would be faster. Or even make an array of 1 bit values. I'm thinking of converting the whole thing to some compiled language. Is PHP just not good for it?

If I do need to convert it to let's say C++, how good are the automatic converters? My script is just a lot of for loops with basic arrays and objects manipulations.

Edit. This function gets called more than any other. It reads few properties of a very simple object, and goes through a very small part of a smallish array to check if there's any element not equal to 0.

function fits($bin, $w, $h, $x, $y) {      $w += $x;     $h += $y;      for ($i = $x; $i < $w; $i++) {          for ($j = $y; $j < $h; $j++) {              if ($bin[$i][$j] !== 0) {                 return false;             }         }     }      return true;     } 

Update: I've tried using 1d array instead of 2d as one of the answers suggested. Since I needed to always have current bin width accessible, I decided to wrap everything in the object. Also, now in every loop the index needs to be calculated. Now the script takes even more time to run. Other techniques didn't bring much performance boost, rather made code less readable. Time for HipHop I guess.

Update: since hiphop php only runs on linux, and I don't have one, I've decided to rewrite the whole thing in C++. It's nice to freshen up the old skills. Also, if I do find a way to use hiphop, it'll be interesting to compare hand-written C++ code and the one hiphop would generate.

Update: I rewrote this thing in c++, on average it works 20 times faster and uses much less memory. Let me see if I can make it even faster.

like image 274
Ivan Vashchenko Avatar asked Feb 04 '11 23:02

Ivan Vashchenko


People also ask

Which is faster array or object in PHP?

The difference between an array numeric and an associative array is a mere 5%, so you can say that they are the same. The use of an object is +100% slower but it is still acceptable in most conditions (aka it uses the double of time).

Is In_array fast?

PHP's in_array() function is really slow.

What does => mean in PHP array?

It means assign the key to $user and the variable to $pass. When you assign an array, you do it like this. $array = array("key" => "value"); It uses the same symbol for processing arrays in foreach statements. The '=>' links the key and the value.

What is Array_keys () used for in PHP?

The array_keys() function returns an array containing the keys.


2 Answers

Array access in PHP can certainly be slow. PHP uses hash tables to implement arrays, i.e. in order to access an element in an array it has to calculate a hash and traverse a linked list. Using a compiled language with real arrays will definitely improve performance, because there a direct memory access is made. For the interested: Code for hash access with string and with integer.

Concerning your code, there are several points I would optimize:

  • return directly, don't break twice.
  • put $file->get_width() and $file->get_height into simple variables. I assume that the height or width doesn't change throughout the process. Remember: Functions in PHP are slow.
  • Use a one-dimensional array, instead of nested arrays. You save one hash lookup per iteration that way. Actually a one-dimensional array is only marginally faster or even slightly slower. Comparison of several ways of saving the data concerning performance and memory usage.

.

function fits($bin, $x, $y, $w, $h) {     $w += $x;     $h += $y;      for ($i = $x; $i < $w; ++$i) {         for ($j = $y; $j < $h; ++$j) {             if ($bin[$i][$j] !== 0) {                 return false;             }         }      }      return true;    } 

Though I'm not sure, why you add $x to the $width / $y to the $height. Don't you want to iterate from the current coordinates to the image boundaries?

like image 153
NikiC Avatar answered Oct 05 '22 08:10

NikiC


The solution to your problem might be https://github.com/facebook/hiphop-php/wiki/

As said by everyone else, PHP is not the optimal language for calculation intensive tasks. It also doesn't really have an array type. What's described as array() in PHP is really a dictionary / hash map. It has some optimizations to double as list, but as you've already discovered it doesn't provide the same runtime behaviour as C pointers and arrays.

HipHop can transform PHP code into optimized C++. It was targetted at string manipulation as well, but it could very well offer a proper array/list transformation.

Disclaimer: I've never tried it. Just wanted to contribute a smart sounding answer here.

like image 22
mario Avatar answered Oct 05 '22 06:10

mario