PHP, Benchmark time

Benchmark array versus object

This benchmark tests the next functionalities:

  • Create a variable.
  • Then, it reads a simple value
  • And it adds to the list (the list is created every round)

And it is an example of the variables used

$array_numeric=[$hello,$second,$third];

$array_not_numeric=['hello'=>$hello,'second'=>$second,'third'=>$third];

$object_constructor=DummyClass('world',0,20.3);

$object_no_constructor=new DummyClass2();
$object_no_constructor->hello='world';
$object_no_constructor->second=0;
$object_no_constructor->third=20.3;

We also test the use of factory, constructor, setter and getters, stdClass and magic methods.

What is a factory? A factory is a function used for creating an entity (in this case, an array).

what is a constructor? A constructor is part of a class and is used to initialize the instance of the object.

Result (smaller is better)

It is the result of the benchmarks in seconds

array numeric no factory array no factory array numeric factory array factory object constructor object no constructor object no constructor setter/getter object no constructor setter/getter (magic) object no constructor stdClass
0.038275957107543945 0.04024696350097656 0.12892484664916992 0.15126800537109375 0.12696218490600586 0.08770990371704102 0.21163702011108398 0.3990211486816406 0.13244986534118652

Result in percentage compared with the smaller result.

array numeric no factory array no factory array numeric factory array factory object constructor object no constructor object no constructor setter/getter object no constructor setter/getter (magic) object no constructor stdClass
0% 5.15% 236.83% 295.2% 231.7% 129.15% 452.92% 942.49% 246.04%

Conclusion:

  • 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).
  • The call to a method or the use of a constructor increases the value considerably. Also, it's better to use an object/constructor than an array/factory. Why? I don't know.
  • The use of setter/getters impacts the performance considerably. If you can then you should avoid that.
  • The use of magic setters and getters is horrible (almost 10 times slower). Is it the reason why Laravel is slow?
    • Also, the setters and getters are vanilla, they don't validate if the field exists of any other validation.
  • And the use of a stdClass (anonymous class) is also bad but not as bad as to use setter and getters.

ps: The test ran 1 million times and the difference is smaller than 0.3 seconds, so is it important?

Let's say we have 100 concurrent users (not a small number but not impossible), and we are processing and returning a list with 1000 values. It is 100x1000 = 100'000 objects. So, if we consider 100'000 objects, then the difference is less than 0.03 seconds in the worst case. However, our systems process more than a single operation, so if we are showing a list of objects, then we also validating, showing other values, validating, reading from the database and storing into the memory and returning to the customer via a web or serialized, so this value could considerable and the use of the CPU is on-top of other processes. It is not a big deal for a small project, but it is important for a big project.

tl/dr

$customer[0]='john'; // faster but it is hard to understand
$customer['name']='john'; // almost as fast as the first one but it is clear to understand (it also uses more memory)
$customer->name='john'; // (where $customer is an object of the class Customer) slower but it still acceptable.
$customer->name='john'; // (where $customer is an object of the class stdClass) the double of slower than to use a class. 
$customer=new Customer('john'); // (constructor) even slower but is still acceptable;
$customer=factory('john'); // (where factory is an array that returns an array). Slower than the use of constructor.
$customer->setName('john'); // bad performance
$customer->name='john'; // (where the class uses a magic method) awful performance, avoid this one.

The code is here (if you want to test it)

9