Самое быстрое жонглирование PHP-типов с помощью функций settype () и * val ()? - PullRequest
2 голосов
/ 24 октября 2009

Я пытаюсь найти самый быстрый способ (в PHP 5), чтобы проверить, является ли значение типом , мне нужно , чтобы оно было. Я создал две строки кода, которые делают одно и то же. Проблема в том, что я не могу понять, какой из них быстрее всего основан на тестах.

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

Я создал следующий тестовый код, но у меня нет больше, чем мой собственный компьютер (Core2Quad + XP 32bit + php5.2.5) и учетная запись Dreamhost, чтобы протестировать его - оба из них показывают примерно одинаковое время для этого код.

$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';

В любом случае, мне было интересно, может быть, здесь есть еще кое-что, чего мне не хватает, в отношении того, какой из этих методов может не только работать быстрее - но также может давать странные результаты. Другое дело, что если это окажется успешным при использовании целых чисел, тогда другие типы, такие как строки и числа с плавающей точкой, также должны работать.

: UPDATE:

Я только что проверил эти методы для типа с плавающей запятой и обнаружил, что settype () был медленнее (.28 сек) по сравнению с floatval () (.21 сек). Поэтому ответ на этот вопрос может быть действительным только для типа int.

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

Ответы [ 4 ]

4 голосов
/ 25 октября 2009

Полагаю, вы спрашиваете из чисто теоретического интереса, потому что различия скорости в данном конкретном случае не могут считаться важными на практике.

давайте рассмотрим исходный код php

Интервал 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

Как вы можете видеть, обе функции используют одну и ту же процедуру convert_to_long (которая, в свою очередь, сводится к вызову библиотеки strtol). settype включает (крошечные) накладные расходы при сравнении второго аргумента со строкой типа, поэтому он должен быть немного медленнее.

самый быстрый метод - использование (int) приведения, потому что он не включает в себя код операции вызова функции, а выполняется непосредственно VM.

1 голос
/ 14 августа 2013

Давайте возьмем простой тест:

<?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";

Мои результаты на 64-битной Ubuntu:

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

На длинных целых картина похожа. Таким образом, (int) является лучшим, но нет реальной причины использовать intval () вместо settype ()

0 голосов
/ 25 октября 2009

Прямое (типовое) литье - самое быстрое. Вот код, который я сейчас использую.

(is_scalar($int) && is_numeric($int) ? (int) $int : 0)
0 голосов
/ 24 октября 2009

Если вы не планируете тестировать значения bazillion, практической разницы в скорости не должно быть. Все, что существует, настолько мало, что ни на что не влияет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...