Pregunta

Estoy tratando de descubrir la forma más rápida (en PHP 5) para verificar que un valor sea escriba que necesito para que sea. Creé dos líneas de código que hacen lo mismo. El problema es que no puedo averiguar cuál es el más rápido basado en puntos de referencia.

(is_scalar($value) ? intval($value) : 0);
settype($value, 'integer');

Creé el siguiente código de prueba, pero no tengo más que mi propia PC (Core2Quad + XP 32bit + php5.2.5) y una cuenta de Dreamhost para probarla, ambas muestran los mismos tiempos para esto código.

$array = array(
    'false' => FALSE,
    'false2'=> 0,
    'false3'=> '0',
    'false4'=> 'FALSE',
    'true'  => TRUE,
    'true2' => 1,
    'true3' => '1',
    'true4' => 'TRUE',

    'char'  => chr(250),
    'char2' => chr(10),
    'utf'   => 0xF0,
    'utf1'  => 0xFE,

    'number' => '452.5435',
    'number2' => '-3948.33e2',
    'number3' => -343.54,
    'number4' => 99.999,
    'number5' => '3jk439fjk23945t324098523.349fj324r',

    'int'   => 2323,
    'int2'  => '2345',
    'int3'  => '0',
    'int4'  => array(),
    'int5'  => '39582347823908270983249078530793249802357846t890234879023490785',
    'int6'  => 3895732890543789324890123467548093248976123890548793289073246789458901234,

    'object3' => new SimpleXMLElement('<xml></xml>'),

    'array' => array(),
    'array2' => array('hello'),
    'array3' => array(3,54,21,0),
    'array4' => array(0.2)
);


$start = microtime(TRUE);

for($x=0;$x<10000;$x++) {
    foreach( $array as $value ) {
        (is_scalar($value) ? intval($value) : 0);
        //settype($value, 'integer');
    }
}

print (microtime(TRUE) - $start). ' seconds';

De todos modos, me preguntaba si podría haber más aquí que me estoy perdiendo en cuanto a cuál de estos métodos podría no solo funcionar más rápido, sino que también daría resultados extraños. Otra cosa es que, si esto demuestra un éxito total con los ints, entonces otros tipos como cadenas y flotadores también deberían funcionar.

: ACTUALIZACIÓN:

Acabo de probar estos métodos con el tipo de coma flotante y descubrí que settype () era más lento (.28 s) en comparación con floatval () (.21 s). Por lo tanto, la respuesta a esta pregunta solo puede ser válida para el tipo int.

//Float
(is_scalar($value) ? floatval($value) : 0);
settype($value, 'float');
¿Fue útil?

Solución

Supongo que está preguntando por puro interés teórico, porque las diferencias de velocidad en este caso particular no pueden considerarse importantes en la práctica.

echemos un vistazo al código fuente de php

intval http: //lxr.php. net / source / php-src / ext / standard / type.c # 142

settype http: //lxr.php. net / source / php-src / ext / standard / type.c # 95

como puede ver, ambas funciones utilizan la misma rutina convert_to_long (que a su vez se reduce a la llamada de la biblioteca strtol). settype incluye (una pequeña) sobrecarga al comparar el segundo argumento con una cadena de tipo, por lo que debería ser un poco más lento.

el método más rápido sería usar (int) cast, porque no implica un código de operación de llamada de función, sino que se ejecuta directamente por VM.

Otros consejos

Tomemos un punto de referencia simple:

<?php
$y = "45678912";

$time_start = microtime(true);
for ($i=0; $i<500000; $i++) {
    $x = $y;
    $x = intval($x);
}
echo "\nintval: " . (microtime(true) - $time_start) . " sec.";

$time_start = microtime(true);
for ($i=0; $i<500000; $i++) {
    $x = $y;
    $x = (int)$x;
}
echo "\n(int): " . (microtime(true) - $time_start) . " sec.";

$time_start = microtime(true);
for ($i=0; $i<500000; $i++) {
    $x = $y;
    settype($x, 'int');
}
echo "\nsettype: " . (microtime(true) - $time_start) . " sec.\n";

Mis resultados en Ubuntu de 64 bits:

intval: 0.47533583641052 sec.
(int): 0.19618892669678 sec.
settype: 0.51951289176941 sec.

En enteros largos la imagen es similar. Entonces (int) es el mejor, pero no hay una razón real para usar intval () en lugar de settype ()

A menos que esté planeando probar valores bazillion, no debería haber ninguna diferencia práctica de velocidad. Cualquiera que exista es tan pequeño que realmente no afecta nada.

El casting directo (tipo) es el más rápido. Aquí está el código que uso ahora.

(is_scalar($int) && is_numeric($int) ? (int) $int : 0)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top