Самый быстрый способ преобразовать строку в целое число в PHP

225

Используя PHP, какой самый быстрый способ преобразовать такую ​​строку: "123" в целое число?

Почему этот конкретный метод самый быстрый? Что произойдет, если он получит неожиданный ввод, например "hello" или массив?

  • 1
    Билл: это не домашнее задание - мне просто любопытно. :)
  • 0
    Почему «самый быстрый» актуален?
Показать ещё 5 комментариев
Теги:
optimization
casting

8 ответов

344
Лучший ответ

Я только что установил быстрое тестирование:

Function             time to run 1 million iterations
--------------------------------------------
(int) "123":                0.55029
intval("123"):              1.0115  (183%)

(int) "0":                  0.42461
intval("0"):                0.95683 (225%)

(int) int:                  0.1502
intval(int):                0.65716 (438%)

(int) array("a", "b"):      0.91264
intval(array("a", "b")):    1.47681 (162%)

(int) "hello":              0.42208
intval("hello"):            0.93678 (222%)

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

Мне было бы интересно узнать, почему.


Обновление: я снова запускал тесты, на этот раз с принуждением (0 + $var)

| INPUT ($x)      |  (int) $x  |intval($x) |  0 + $x   |
|-----------------|------------|-----------|-----------|
| "123"           |   0.51541  |  0.96924  |  0.33828  |
| "0"             |   0.42723  |  0.97418  |  0.31353  |
| 123             |   0.15011  |  0.61690  |  0.15452  |
| array("a", "b") |   0.8893   |  1.45109  |  err!     |
| "hello"         |   0.42618  |  0.88803  |  0.1691   |
|-----------------|------------|-----------|-----------|

Добавление: Я столкнулся с немного неожиданным поведением, о котором вы должны знать при выборе одного из этих методов:

$x = "11";
(int) $x;      // int(11)
intval($x);    // int(11)
$x + 0;        // int(11)

$x = "0x11";
(int) $x;      // int(0)
intval($x);    // int(0)
$x + 0;        // int(17) !

$x = "011";
(int) $x;      // int(11)
intval($x);    // int(11)
$x + 0;        // int(11) (not 9)

Протестировано с использованием PHP 5.3.1

  • 9
    Вероятно, это связано с тем, что intval () вызывает вызов функции, в то время как приведение обрабатывается непосредственно в калькуляторе выражений интерпретатора. Это также может быть причиной того, что коэрция еще быстрее.
  • 10
    Ваш пример приведения может быть еще более упрощен с помощью малоизвестного унарного оператора плюс в php. $ x + 0 -> + $ x
Показать ещё 5 комментариев
32

Я лично считаю, что кастинг - самый красивый.

$iSomeVar = (int) $sSomeOtherVar;

Если будет отправлена ​​строка типа "Hello", она будет отлита от целого 0. Для строки типа "22 года" она будет отлита до целого числа 22. Все, что не может разобрать на число, становится 0.

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

  • 7
    интересно, что массивы приводятся к 1. go figure.
  • 2
    @nickf Не так - это может быть также приведено к 0. Он преобразует свое логическое (true | false) значение в целое число - «false» = 0, «true» = 1. Массив false, если он на 100% пуст, и true, если он содержит ЛЮБЫЕ данные, даже если он просто пуст строки или значения NULL. Если вы приведете пустой массив к целому числу, оно станет 0. (Да, я знаю это старое!)
15

Запустите тест.

   string coerce:          7.42296099663
   string cast:            8.05654597282
   string fail coerce:     7.14159703255
   string fail cast:       7.87444186211

Это был тест, который запускал каждый сценарий 10 000 000 раз.: -)

Co-ercion 0 + "123"

Литье (integer)"123"

Я думаю, что Co-ercion немного быстрее. О, и попытка 0 + array('123') является фатальной ошибкой в ​​PHP. Возможно, вы захотите, чтобы ваш код проверял тип поставляемого значения.

Мой тестовый код ниже.


function test_string_coerce($s) {
    return 0 + $s;
}

function test_string_cast($s) {
    return (integer)$s;
}

$iter = 10000000;

print "-- running each text $iter times.\n";

// string co-erce
$string_coerce = new Timer;
$string_coerce->Start();

print "String Coerce test\n";
for( $i = 0; $i < $iter ; $i++ ) {
    test_string_coerce('123');
}

$string_coerce->Stop();

// string cast
$string_cast = new Timer;
$string_cast->Start();

print "String Cast test\n";
for( $i = 0; $i < $iter ; $i++ ) {
    test_string_cast('123');
}

$string_cast->Stop();

// string co-erce fail.
$string_coerce_fail = new Timer;
$string_coerce_fail->Start();

print "String Coerce fail test\n";
for( $i = 0; $i < $iter ; $i++ ) {
    test_string_coerce('hello');
}

$string_coerce_fail->Stop();

// string cast fail
$string_cast_fail = new Timer;
$string_cast_fail->Start();

print "String Cast fail test\n";
for( $i = 0; $i < $iter ; $i++ ) {
    test_string_cast('hello');
}

$string_cast_fail->Stop();

// -----------------
print "\n";
print "string coerce:          ".$string_coerce->Elapsed()."\n";
print "string cast:            ".$string_cast->Elapsed()."\n";
print "string fail coerce:     ".$string_coerce_fail->Elapsed()."\n";
print "string fail cast:       ".$string_cast_fail->Elapsed()."\n";


class Timer {
    var $ticking = null;
    var $started_at = false;
    var $elapsed = 0;

    function Timer() {
        $this->ticking = null;
    }

    function Start() {
        $this->ticking = true;
        $this->started_at = microtime(TRUE);
    }

    function Stop() {
        if( $this->ticking )
            $this->elapsed = microtime(TRUE) - $this->started_at;
        $this->ticking = false;
    }

    function Elapsed() {
        switch( $this->ticking ) {
            case true: return "Still Running";
            case false: return $this->elapsed;
            case null: return "Not Started";
        }
    }
}
  • 0
    Я добавил settype к этому тесту и запустил его, используя PHP 7. settype получилось немного впереди, и значительно улучшилось быстродействие по всем параметрам: string coerce: 1.9255340099335 string cast: 1.5142338275909 string settype: 4.149735212326 string отказов сбой settype: 4.149735212326
8

Вы можете просто преобразовать длинную строку в целое число с помощью FLOAT

$float = (float)$num;

Или, если вы хотите, чтобы целое число не плавающее, тогда перейдите к

$float = (int)$num;

Например,

(int)   "1212.3"   = 1212 
(float) "1212.3"   = 1212.3
  • 1
    А? Если вам нужен int, почему бы вам не использовать (int) ? Может быть верно, что если строка содержит целое число, то (float) вернет значение, которое во многом похоже на целое число (даже если его внутренний тип, вероятно, float ), но зачем вам это делать, если спецификация вернуть целое значение? Предположим, что входящая строка "1,3"? Вы не получите целое число. Кроме того, ради того, чтобы кто-нибудь читал код в будущем, вы должны сказать, что вы имеете в виду. Если вы имеете в виду «это должно быть целое число», то скажите (int) , а не (float) .
7

целочисленное выражение из любой строки

$in = 'tel.123-12-33';

preg_match_all('!\d+!', $in, $matches);
$out =  (int)implode('', $matches[0]);

//$out = '1231233';

  • 0
    Ты лучший из лучших из лучших! Я потратил часы, чтобы преобразовать некоторую переменную из строки данных json в целое число, только ваш метод помог! благодарю вас!
7
$int = settype("100", "integer"); //convert the numeric string to int
  • 3
    Я считаю, что некоторые ссылки или доказательства в порядке!
  • 0
    $ int на самом деле здесь будет логическим, если оператор сработает, но это не так, поскольку первый параметр settype () передается по ссылке и поэтому должен быть переменной var.
3

Ran - эталон, и оказывается, что самый быстрый способ получить реальное целое число (используя все доступные методы) -

$foo = (int)+"12.345";

Просто используя

$foo = +"12.345";

возвращает float.

  • 2
    Это быстрее, чем просто (int)"12.345" ? На какой процент быстрее?
3

Больше специальных результатов:

$ time php -r 'for ($x = 0;$x < 999999999; $x++){$i = (integer) "-11";}'     

real    2m10.397s
user    2m10.220s
sys     0m0.025s

$ time php -r 'for ($x = 0;$x < 999999999; $x++){$i += "-11";}'              

real    2m1.724s
user    2m1.635s
sys     0m0.009s

$ time php -r 'for ($x = 0;$x < 999999999; $x++){$i = + "-11";}'             

real    1m21.000s
user    1m20.964s
sys     0m0.007s
  • 0
    Было бы лучше написать проверяемый оператор в каждом цикле по 10 раз, чтобы время не зависело от издержек цикла. Например, { $i = +"-11"; $i = +"-11"; $i= +"-11"; $i= +"-11"; ... } Также рискованно использовать буквальное значение "-11" напрямую, если вы не уверены, что язык не выполнит часть работы во время компиляции. Возможно, это нормально для динамического языка, такого как PHP, но я упомяну для дальнейшего использования, если тестирую формулы на других языках. Безопаснее установить переменную $x = "-11" перед циклом тестирования, а затем использовать ее. Так что внутренний код равен $i =+$x .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню