Which one uses more memory / processor in PHP? If or switch?

Question:

An optimized website is not only with fewer tags, styles or plugins, I also think it necessary to optimize the resources on the server side, for better performance.

So the use of an if can help to execute several data that can be executed in only one or through an elseif execute a different script.

if($var === 'a' || $var === 'b' || $var === 'c'){
    //Ejecutar
}elseif($var1 === 'd'){
    //Ejecutar
} else {
    //Default
}

And in the use of a switch is executed in a very elegant way although it has its cons, for example having to add a new switch when the variable is different, for example:

switch ($var) {
    case 'a':
        # code...
        break;
    case 'b':
        # code...
        break;
    case 'c':
        # code...
        break;
    default:
        # code...
        break;
}
switch ($var1) {
    case 'd':
        # code...
        break;
}

Both use looks simple, but which one takes more resources, more than an opinion, is an important issue that I think should be taken into account for applications with much higher performance.

Answer:

Foreword

Each use case could yield different results for different reasons, so the reasoned statement in this answer is only valid in particular to this use case, although it could be defined as a fairly general case.

So we can say that, in this particular case, the performance of a switch / case is superior to that of if / else blocks in terms of execution speed, but that in terms of memory use, a switch / case is worse compared to the if / else .

Also, in all cases the switch / case blocks would fail when comparing the initial value of $letra in the tests, which is 0 , when comparing it with the letter a , since 0 == 'a' returns true (the type comparison using switch / case ), while 0 === 'a' returns false (type of comparison used in if ):

$ php7.2 -r 'var_dump(0 == "a");'
bool(true)
$ php7.2 -r 'var_dump(0 === "a");'
bool(false)

Test Environment

For testing I have created two files:

if.php

<?php
$letras = 'abcdefghijk';
for ($c = 0; $c < 3; $c++) {
  $letra = 0;
  $caso1 = 0;
  $caso2 = 0;
  $start = microtime(true);
  for ($i = 0; $i < 100000000; $i++, $letra = $letras[$i % strlen($letras)]) {
    if ($letra === 'a' || $letra === 'b' || $letra === 'c') {
      $caso1++;
    } else if ($letra === 'd') {
      $caso2++;
    }
  }
  printf(
    '[if-else %d] Time: %.3f s (c1: %d, c2: %d)%s',
    $c,
    microtime(true) - $start,
    $caso1,
    $caso2,
    PHP_EOL
  );
}

switch.php

<?php
$letras = 'abcdefghijk';
for ($c = 0; $c < 3; $c++) {
  $letra = 0;
  $caso1 = 0;
  $caso2 = 0;
  $start = microtime(true);
  for ($i = 0; $i < 100000000; $i++, $letra = $letras[$i % strlen($letras)]) {
    switch($letra) {
      case 'a':
      case 'b':
      case 'c':
        $caso1++;
        break;
      case 'd':
        $caso2++;
    }
  }
  printf(
    '[switch %d] Time: %.3f s (c1: %d, c2: %d)%s',
    $c,
    microtime(true) - $start,
    $caso1,
    $caso2,
    PHP_EOL
  );
}

Execution time

And I have run both scripts consecutively and in the same PHP environment:

$ php7.2 -r "require 'if.php'; require 'switch.php';"
[if-else 0] Time: 6.232 s (c1: 27272727, c2: 9090909)
[if-else 1] Time: 6.228 s (c1: 27272727, c2: 9090909)
[if-else 2] Time: 6.225 s (c1: 27272727, c2: 9090909)
[switch 0] Time: 3.654 s (c1: 27272728, c2: 9090909)
[switch 1] Time: 3.653 s (c1: 27272728, c2: 9090909)
[switch 2] Time: 3.657 s (c1: 27272728, c2: 9090909)

Memory usage

To calculate the impact in memory I have used:

$ php -r "require 'if.php'; echo memory_get_peak_usage(), PHP_EOL;"
[if-else 0] Time: 6.245 s (c1: 27272727, c2: 9090909)
[if-else 1] Time: 6.224 s (c1: 27272727, c2: 9090909)
[if-else 2] Time: 6.218 s (c1: 27272727, c2: 9090909)
432832
$ php -r "require 'switch.php'; echo memory_get_peak_usage(), PHP_EOL;"
[switch 0] Time: 4.032 s (c1: 27272728, c2: 9090909)
[switch 1] Time: 4.038 s (c1: 27272728, c2: 9090909)
[switch 2] Time: 4.027 s (c1: 27272728, c2: 9090909)
433136

Base case:

In order to calculate the increase in time and memory of the case with respect to the if a base case must be taken in which time is taken into account all that is not related to the tests:

base.php

<?php
$letras = 'aaaa';
for ($c = 0; $c < 3; $c++) {
  $letra = 0;
  $caso1 = 0;
  $caso2 = 0;
  $start = microtime(true);
  for ($i = 0; $i < 100000000; $i++, $letra = $letras[$i % strlen($letras)]) {
  }
  printf(
    '[if-else %d] Time: %.3f s (c1: %d, c2: %d)%s',
    $c,
    microtime(true) - $start,
    $caso1,
    $caso2,
    PHP_EOL
  );
}

The results:

$ php -r "require 'base.php'; echo memory_get_peak_usage(), PHP_EOL;"
[if-else 0] Time: 2.545 s (c1: 0, c2: 0)
[if-else 1] Time: 2.545 s (c1: 0, c2: 0)
[if-else 2] Time: 2.544 s (c1: 0, c2: 0)
432256

Results:

  • Best execution time: switch . 3,687 > 1,109 ( 232% more).
  • Better memory usage: if . 576 < 880 ( 53% more).

Other use cases

As I said in the prologue to this answer, it depends on the case the results can increase or decrease.

A very quick example showing how a simple change can affect is modifying this line in both scripts:

$letras = 'abcd';

Now throwing some more adjusted results between both:

$ php7.2 -r "require 'if.php'; require 'switch.php';"
[if-else 0] Time: 5.478 s (c1: 74999999, c2: 25000000)
[if-else 1] Time: 5.485 s (c1: 74999999, c2: 25000000)
[if-else 2] Time: 5.483 s (c1: 74999999, c2: 25000000)
[switch 0] Time: 4.140 s (c1: 75000000, c2: 25000000)
[switch 1] Time: 4.141 s (c1: 75000000, c2: 25000000)
[switch 2] Time: 4.140 s (c1: 75000000, c2: 25000000)
  • Best execution time: switch . 2,938 > 1,595 ( 84% more).

Change the string to the first case of the if or :

$letras = 'aaaa';

I would bring the results even closer:

$ php7.2 -r "require 'if.php'; require 'switch.php';"
[if-else 0] Time: 4.259 s (c1: 99999999, c2: 0)
[if-else 1] Time: 4.254 s (c1: 99999999, c2: 0)
[if-else 2] Time: 4.275 s (c1: 99999999, c2: 0)
[switch 0] Time: 3.829 s (c1: 100000000, c2: 0)
[switch 1] Time: 3.834 s (c1: 100000000, c2: 0)
[switch 2] Time: 3.832 s (c1: 100000000, c2: 0)
  • Best execution time: switch . 1,714 > 1,287 ( 33% more).
Scroll to Top