:::: MENU ::::

PHP: true vs 1

Muchos habréis oído la típica frase de «utiliza 1 en lugar de true, es más óptimo».
Pues no… ¿pero sí?

Vamos a explicarlo. En primer lugar, imaginemos que hacemos algo tan simple como:

<?php
if(true) {}

Esto per se sería más rápido que:

<?php
if(1) {}

Os preguntaréis el porqué, la respuesta es sencilla; si nosotros le proporcionamos un booleano, este es el tipo que espera recibir, por lo que no tiene que realizar ningún tipo de conversión.

Para corroborarlo, hice un benchmark de la siguiente forma:

<?php
while(true) {
    $startTime = round(microtime(true) * 1000);
    for($i = 0; $i < 200000000; $i++)
        if(1) {}
    $endTime = round(microtime(true) * 1000) - $startTime;
    echo '1: ', $endTime, "ms \n";
    file_put_contents('1.txt', $endTime . "\n", FILE_APPEND);
    
    $startTime = round(microtime(true) * 1000);
    for($i = 0; $i < 200000000; $i++)
        if(true) {}
    $endTime = round(microtime(true) * 1000) - $startTime;
    echo 'true: ', $endTime, "ms \n";
    file_put_contents('true.txt', $endTime . "\n", FILE_APPEND);
}

El resultado fue que, efectivamente, utilizar true en lugar de 1 es más eficiente tal y como se ve a continuación:

Eje X: Iteración // Eje Y: milisegundos (menos es mejor)

En el resultado observamos claramente que true, como predecimos, es más eficiente, en concreto, de media un 12% más eficiente que 1.

¿A qué se debe?
Al no recibir un tipo booleano, tiene que convertir de entero a booleano. PHP comprueba el valor del entero, si este es igual a 0, será false, de lo contrario, true; dicha operación es poco costosa, pero si se repite muchas veces puede llegar a suponer un incremento del tiempo de carga.

Por insignificante que parezca, programar de forma óptima es esencial para grandes compañías que reciben millones de peticiones al día, pues a la larga, cada pequeño detalle suma, y eso puede suponer grandes cantidades de dinero en costes.

La forma más eficiente de hacerlo por nuestra parte es hacer un cast, es decir:

<?php
$int = 1; // 1
$bool = (boolean) $int; // true

No obstante, hay otra forma ligeramente más ineficiente de hacerlo, pero de nuevo, más corta, la doble negación.
Sabemos que si negamos un entero, lo va a convertir a booleano tal y como hemos descrito para después sacar su contrario. Ahora, si negamos el resultado de eso, obtendremos el resultado de la conversión inicial, ya que anulamos la primera negación:

<?php
$int = 1; // 1
$boolOnce = !$int; // false
$boolTwice = !!$int; // true

No obstante…
Hemos hablado de que es más óptimo, pero… ¿en la práctica es así?
Como sabréis, PHP es un lenguaje interpretado y por ende, cada vez que tiene que ejecutar algo tiene que leer el archivo de principio a fin (excepto si utilizamos herramientas como HHVM de Facebook, en cuyo caso todo lo que viene a continuación queda invalidado).

Para ser justos con la gente que argumenta que utilizar 1 es más óptimo al ser interpretado, he querido hacer un benchmark en el cual lee la parte de ‘if(true o 1)’ cada vez:

<?php
while(true) {
    $startTime = round(microtime(true) * 1000);
    for($i = 0; $i < 500000; $i++)
        eval(file_get_contents('read1.php'));
    $endTime = round(microtime(true) * 1000) - $startTime;
    echo '1: ', $endTime, "ms \n";
    file_put_contents('1-ev.txt', $endTime . "\n", FILE_APPEND);
    
    $startTime = round(microtime(true) * 1000);
    for($i = 0; $i < 500000; $i++)
        eval(file_get_contents('readtrue.php'));
    $endTime = round(microtime(true) * 1000) - $startTime;
    echo 'true: ', $endTime, "ms \n";
    file_put_contents('true-ev.txt', $endTime . "\n", FILE_APPEND);
}

He aquí los resultados:

Eje X: Iteración // Eje Y: milisegundos (menos es mejor)

Aunque en el gráfico parezca que ‘1’ gana a ‘true’ por goleada, nada más lejos de la realidad, ‘1’ tan solo gana por un 0,51% de media en más de mil resultados.

En conclusión, dado que PHP es interpretado, es susceptible a que pequeños detalles de este estilo le afecten en su rendimiento. No podemos concluir que ‘1’ sea mejor que ‘true’, o viceversa, pues dependerá del caso.
PHP tiene muchísimas posibilidades, no tan solo podemos desarrollar una web, en cuyo caso, al tener que leer el archivo, utilizaríamos ‘1’; también podemos programar algo que se ejecute en consola, o algo que tenga muchas iteraciones, en cuyo caso sería mejor ‘true’.

Personalmente siempre utilizaría true, son necesarias pocas iteraciones para que sea rentable utilizarlo y considero que hacer que convierta de entero a booleano por detrás es una mala práctica; prueba de ello es que en lectura solo hay un 0,5% de diferencia y en iteración gana ‘true’ con más de un 12% de ventaja.
Finalmente, ‘true’ es más legible, y así está diseñado el lenguaje.