Skip to content

Instantly share code, notes, and snippets.

@netojoaobatista
Last active August 30, 2017 13:38
Show Gist options
  • Save netojoaobatista/7582693 to your computer and use it in GitHub Desktop.
Save netojoaobatista/7582693 to your computer and use it in GitHub Desktop.
<?php
$a = 10;
if ($a > 5) {
$b = 5;
} else {
$b = 10;
}
<?php
$a = 10;
if (5 < $a) {
$b = 5;
} else {
$b = 10;
}
<?php
$a = 10;
$b = 5 < $a? 5: 10;

Esse teste é, na verdade, uma tentativa de resposta para a pergunta:

Existe alguma vantagem ao se utilizar da segunda forma ou é apenas uma questão de estética/semântica?

$itemRecebidoViaPost = $_POST['item'];

// Primeira forma if ( $itemRecebidoViaPost == 'item-desejado' ) {

}

// Segunda forma if ( 'item-desejado' == $itemRecebidoViaPost ) {

}

Além das duas formas, que originaram a pergunta, ainda adicionei um terceiro caso, sobre o if ternário. O opcode é o mesmo para ambos, porém, independentemente de testar if (5 < $a) ou if ($a > 5), o PHP faz a checagem IS_SMALLER 5, !0, ou seja if ($expected < $actual), que também é a lógica empregada pelo PHPUnit e outros frameworks de teste unitário, como JUnit.

Primeiro Caso

Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 8
Branch analysis from position: 5
Jump found. Position 1 = 10
Branch analysis from position: 10
Return found
Branch analysis from position: 8
Return found
filename:       /src/1st-case.php
function name:  (null)
number of ops:  11
compiled vars:  !0 = $a, !1 = $b
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   EXT_STMT                                                 
	 1      ASSIGN                                                   !0, 10
   4     2      EXT_STMT                                                 
	 3      IS_SMALLER                                       ~1      5, !0
	 4    > JMPZ                                                     ~1, ->8
   5     5  >   EXT_STMT                                                 
	 6      ASSIGN                                                   !1, 5
   6     7    > JMP                                                      ->10
   7     8  >   EXT_STMT                                                 
	 9      ASSIGN                                                   !1, 10
   9    10  > > RETURN                                                   1

branch: #  0; line:     2-    4; sop:     0; eop:     4; out1:   5; out2:   8
branch: #  5; line:     5-    6; sop:     5; eop:     7; out1:  10
branch: #  8; line:     7-    9; sop:     8; eop:     9; out1:  10
branch: # 10; line:     9-    9; sop:    10; eop:    10
path #1: 0, 5, 10, 
path #2: 0, 8, 10,

Segundo Caso

Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 8
Branch analysis from position: 5
Jump found. Position 1 = 10
Branch analysis from position: 10
Return found
Branch analysis from position: 8
Return found
filename:       /src/2nd-case.php
function name:  (null)
number of ops:  11
compiled vars:  !0 = $a, !1 = $b
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   EXT_STMT                                                 
	 1      ASSIGN                                                   !0, 10
   4     2      EXT_STMT                                                 
	 3      IS_SMALLER                                       ~1      5, !0
	 4    > JMPZ                                                     ~1, ->8
   5     5  >   EXT_STMT                                                 
	 6      ASSIGN                                                   !1, 5
   6     7    > JMP                                                      ->10
   7     8  >   EXT_STMT                                                 
	 9      ASSIGN                                                   !1, 10
   9    10  > > RETURN                                                   1

branch: #  0; line:     2-    4; sop:     0; eop:     4; out1:   5; out2:   8
branch: #  5; line:     5-    6; sop:     5; eop:     7; out1:  10
branch: #  8; line:     7-    9; sop:     8; eop:     9; out1:  10
branch: # 10; line:     9-    9; sop:    10; eop:    10
path #1: 0, 5, 10, 
path #2: 0, 8, 10,

O mesmo não ocorre com uma verificação de igualdade. Nesse tipo de comparação, o opcode gerado segue a lógica empregada no código, por exemplo:

<?php
$a = 10;

if (5 == $a) {
    $b = 5;
} else {
    $b = 10;
}

Se observar o opcode, IS_EQUAL 5, !0:

Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 8
Branch analysis from position: 5
Jump found. Position 1 = 10
Branch analysis from position: 10
Return found
Branch analysis from position: 8
Return found
filename:       /src/4th-case.php
function name:  (null)
number of ops:  11
compiled vars:  !0 = $a, !1 = $b
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   EXT_STMT                                                 
	 1      ASSIGN                                                   !0, 10
   4     2      EXT_STMT                                                 
	 3      IS_EQUAL                                         ~1      5, !0
	 4    > JMPZ                                                     ~1, ->8
   5     5  >   EXT_STMT                                                 
	 6      ASSIGN                                                   !1, 5
   6     7    > JMP                                                      ->10
   7     8  >   EXT_STMT                                                 
	 9      ASSIGN                                                   !1, 10
   9    10  > > RETURN                                                   1

branch: #  0; line:     2-    4; sop:     0; eop:     4; out1:   5; out2:   8
branch: #  5; line:     5-    6; sop:     5; eop:     7; out1:  10
branch: #  8; line:     7-    9; sop:     8; eop:     9; out1:  10
branch: # 10; line:     9-    9; sop:    10; eop:    10
path #1: 0, 5, 10, 
path #2: 0, 8, 10,

Invertendo a ordem da comparação:

<?php
$a = 10;

if ($a == 5) {
    $b = 5;
} else {
    $b = 10;
}

Se observar o opcode, IS_EQUAL !0, 5:

Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 8
Branch analysis from position: 5
Jump found. Position 1 = 10
Branch analysis from position: 10
Return found
Branch analysis from position: 8
Return found
filename:       /src/5th-case.php
function name:  (null)
number of ops:  11
compiled vars:  !0 = $a, !1 = $b
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   EXT_STMT                                                 
	 1      ASSIGN                                                   !0, 10
   4     2      EXT_STMT                                                 
	 3      IS_EQUAL                                         ~1      !0, 5
	 4    > JMPZ                                                     ~1, ->8
   5     5  >   EXT_STMT                                                 
	 6      ASSIGN                                                   !1, 5
   6     7    > JMP                                                      ->10
   7     8  >   EXT_STMT                                                 
	 9      ASSIGN                                                   !1, 10
   9    10  > > RETURN                                                   1

branch: #  0; line:     2-    4; sop:     0; eop:     4; out1:   5; out2:   8
branch: #  5; line:     5-    6; sop:     5; eop:     7; out1:  10
branch: #  8; line:     7-    9; sop:     8; eop:     9; out1:  10
branch: # 10; line:     9-    9; sop:    10; eop:    10
path #1: 0, 5, 10, 
path #2: 0, 8, 10,

Agora o if ternário:

Terceiro caso

Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 7
Branch analysis from position: 5
Jump found. Position 1 = 8
Branch analysis from position: 8
Return found
Branch analysis from position: 7
Return found
filename:       /src/3rd-case.php
function name:  (null)
number of ops:  10
compiled vars:  !0 = $a, !1 = $b
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   EXT_STMT                                                 
	 1      ASSIGN                                                   !0, 10
   3     2      EXT_STMT                                                 
	 3      IS_SMALLER                                       ~1      5, !0
	 4    > JMPZ                                                     ~1, ->7
	 5  >   QM_ASSIGN                                        ~2      5
	 6    > JMP                                                      ->8
	 7  >   QM_ASSIGN                                        ~2      10
	 8  >   ASSIGN                                                   !1, ~2
   4     9    > RETURN                                                   1

branch: #  0; line:     2-    3; sop:     0; eop:     4; out1:   5; out2:   7
branch: #  5; line:     3-    3; sop:     5; eop:     6; out1:   8
branch: #  7; line:     3-    3; sop:     7; eop:     7; out1:   8
branch: #  8; line:     3-    4; sop:     8; eop:     9
path #1: 0, 5, 8, 
path #2: 0, 7, 8,

Analizando o opcode do terceiro caso, teoricamente, mesmo que insignificantemente, ele deveria ser mais rápido. Mas na prática, não dá para afirmar se um é mais rápido que o outro em nenhum dos três casos.

O código foi testado no PHP 5.4.21

PHP 5.4.21 (cli) (built: Oct 17 2013 05:21:08) 
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
    with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans

Antes do PHP 5.4, porém, existia uma situação que poderia fazer com que o terceiro caso fosse mais lento em determinadas situações. O PHP fazia uma cópia do conteúdo da variável. Então, se o volume de dados armazenados em uma determinada variável fosse muito grande, então a cópia do conteúdo fazia com que o terceiro caso fosse mais lento. Essa situação não acontecia com objetos, pois o PHP 5.3 já trabalhava com referências para os objetos, mas se fosse uma string muito grande, ou um array muito grande, a cópia do conteúdo faria o terceiro caso mais lento, quando comparado com os dois primeiros.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment