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

Какой самый быстрый способ преобразовать строку типа "123" в целое число с помощью PHP?

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

Билл: это не домашнее задание - мне просто любопытно. :)

nickf 27.10.2008 08:22

ну, если это не повредит (читабельность), почему бы не сделать что-то наиболее эффективным способом?

nickf 02.12.2008 16:40

Если это не вредит скорости, почему бы не сделать вещи максимально читаемыми?

Andy Lester 21.10.2009 23:06

@ Энди, посмотри на тесты производительности ниже. Разница между (int) и intval() может составлять более 400%!

nickf 22.10.2009 02:53

самое быстрое имеет значение, потому что скорость имеет значение для взаимодействия с пользователем. Когда у вас выполняется много операций, вы хотите, чтобы они выполнялись БЫСТРО!

philipp 17.04.2012 08:24

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

totallyNotLizards 22.10.2012 19:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
255
6
363 624
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Ответ принят как подходящий

Я только что провел небольшое упражнение по сравнительному анализу:

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)

Tested using PHP 5.3.1

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

staticsan 27.10.2008 09:09

Ваш пример принуждения можно еще больше упростить, используя малоизвестный унарный оператор плюс в php. $ x + 0 -> + $ x

Ozzy 02.04.2013 12:57

@Ozzy Это круто. Спасибо за совет! +"15" == 15

caiosm1005 02.05.2014 06:24

@nickf Против 100% ... чего? Вы говорите, что intval является самым медленным, но вы не даете простого ясного ответа, как самый быстрый по запросу OP.

John 07.01.2015 22:44

@John, поскольку он тестирует только два случая в этом первом коде, (int) и intval, и в каждой паре дает% для intval, базовым случаем должен быть (int). Но у вас есть хороший аргумент, что было бы яснее, если бы он сказал это прямо, тем более, что позже он добавил третий случай!

ToolmakerSteve 21.08.2015 02:55

... и эта добавленная таблица показывает, что третий случай 0+$x (или просто +$x согласно комментариям) быстрее, чем оба исходных, при условии, что значения - time to run 1 million iterations, согласно исходной таблице.

ToolmakerSteve 21.08.2015 03:00

Есть ли какие-либо изменения в этих результатах в более новых версиях PHP?

Artyom 22.08.2017 13:19

Проведите тест.

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

Я добавил settype в этот тест и запустил его с помощью PHP 7. Приведение вышло немного впереди и значительно улучшило производительность по всем параметрам: string coerce: 1.9255340099335 string cast: 1.5142338275909 string settype: 4.149735212326 string fail coerce: 1.2346560955048 string fail cast: 1.3967711925507 string тип набора ошибок: 4.149735212326

bstoney 11.08.2016 03:54

Лично я считаю, что кастинг самый красивый.

$iSomeVar = (int) $sSomeOtherVar;

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

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

интересно, массивы приводятся к 1. go figure.

nickf 27.10.2008 15:09

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

Super Cat 22.08.2015 03:38
$int = settype("100", "integer"); //convert the numeric string to int

Я считаю, что нужны ссылки или доказательства!

Mehran 29.10.2012 18:58

$ int на самом деле был бы здесь логическим, если бы оператор работал, но это не так, поскольку первый параметр settype () передается по ссылке и поэтому должен быть var.

Queue 06.03.2014 22:55

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

$float = (float)$num;

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

$float = (int)$num;

Например,

(int)   "1212.3"   = 1212 
(float) "1212.3"   = 1212.3

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

ToolmakerSteve 21.08.2015 03:17

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

$ 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

Было бы лучше написать тестируемый оператор 10 раз в каждом цикле, чтобы время не зависело от накладных расходов цикла. Например. { $i = +"-11"; $i = +"-11"; $i= +"-11"; $i= +"-11"; ... }. Также рискованно использовать буквальное значение "-11" напрямую, если вы не уверены, что язык не выполняет часть работы во время компиляции. Вероятно, подходит для динамического языка, такого как PHP, но я упомяну для справки в будущем, если тестируете формулы на других языках. Безопаснее установить переменную $x = "-11" перед тестовым циклом, а затем использовать ее. Так что внутренний код - $i =+$x.

ToolmakerSteve 21.08.2015 03:13

целое исключение из любой строки

$ in = 'тел.123-12-33';

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

// $ out = '1231233';

Вы лучший из лучших! Я потратил часы на преобразование некоторой переменной из строки данных json в целое число, помог только ваш метод! благодарю вас!

Kamnibula 10.06.2015 09:26

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

$foo = (int)+"12.345";

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

$foo = +"12.345";

возвращает число с плавающей запятой.

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

ToolmakerSteve 21.08.2015 03:23

Другие вопросы по теме