PHP kullanarak, böyle bir dizeyi "123"
tamsayıya dönüştürmenin en hızlı yolu nedir?
Neden bu özel yöntem en hızlı? "hello"
Veya bir dizi gibi beklenmedik girdiler alırsa ne olur ?
(int)
ve intval()
% 400 üzerinde olabilir!
PHP kullanarak, böyle bir dizeyi "123"
tamsayıya dönüştürmenin en hızlı yolu nedir?
Neden bu özel yöntem en hızlı? "hello"
Veya bir dizi gibi beklenmedik girdiler alırsa ne olur ?
(int)
ve intval()
% 400 üzerinde olabilir!
Yanıtlar:
Kısa bir kıyaslama alıştırması yaptım:
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%)
Ortalama olarak, intval () çağrısı iki buçuk kat daha yavaştır ve girdiniz zaten bir tamsayı ise fark en büyüktür.
Neden olsa bilmek istiyorum .
Güncelleme: Testleri tekrar yapıyorum, bu sefer baskı ile (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 |
|-----------------|------------|-----------|-----------|
Zeyilname: Bu yöntemlerden birini seçerken bilmeniz gereken biraz beklenmedik bir davranışla karşılaştım:
$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 kullanılarak test edilmiştir
+"15" == 15
(int)
ve intval
ve her çiftinde, bir% verir intval
, baz harf olmalıdır (int)
. Ancak, özellikle daha sonra üçüncü bir dava eklediğinden bu kadar açık bir şekilde söylemiş olmanın daha net olacağı konusunda iyi bir fikriniz var!
Şahsen dökümün en güzel olduğunu hissediyorum.
$iSomeVar = (int) $sSomeOtherVar;
'Merhaba' gibi bir dize gönderilirse, tamsayı 0'a dönüştürülür. '22 yaşında 'gibi bir dize için tamsayı 22'ye dönüştürülür. Bir sayıya ayrıştırılamayan her şey 0 olur.
Gerçekten hıza İHTİYACINIZ varsa, sanırım buradaki diğer öneriler zorlamanın en hızlı olduğunu varsayarken doğrudur.
Bir test yapın.
string coerce: 7.42296099663
string cast: 8.05654597282
string fail coerce: 7.14159703255
string fail cast: 7.87444186211
Bu, her senaryoyu 10.000.000 kez çalıştıran bir testti. :-)
Ortak eris 0 + "123"
Döküm (integer)"123"
Bence Co-ercion biraz daha hızlı. Oh, ve denemek 0 + array('123')
PHP'de ölümcül bir hatadır. Kodunuzun sağlanan değerin türünü kontrol etmesini isteyebilirsiniz.
Test kodum aşağıda.
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
Bu teste ekledim ve PHP 7 kullanarak çalıştırdım. Cast biraz önde çıktı ve hepsine büyük bir performans artışı: string coerce: 1.9255340099335 string cast: 1.5142338275909 string settype: 4.149735212326 string fail coerce: 1.2346560955048 string fail cast: 1.3967711925507 string fail set
FLOAT kullanarak uzun dizeyi tamsayıya dönüştürebilirsiniz
$float = (float)$num;
Veya tamsayı val kayan istemiyorsanız
$float = (int)$num;
Örn.
(int) "1212.3" = 1212
(float) "1212.3" = 1212.3
(int)
? Dize bir tamsayı içeriyorsa, bunun tamsayı (float)
gibi çok fazla davranan bir değer döndüreceği doğru olabilir (iç türü büyük olasılıkla olsa da float
), ancak belirtim bir tamsayı değeri döndürmek için bunu neden yapmalısınız? ? Gelen dize "1.3" olduğunu varsayalım? Bir tamsayı elde edemezsiniz. Ayrıca, gelecekte kodu okuyan herkes uğruna ne demek istediğinizi söylemelisiniz. "Bir tamsayı olmalı" demek istiyorsanız (int)
, değil deyin (float)
.
$int = settype("100", "integer"); //convert the numeric string to int
herhangi bir dizeden tamsayı hariç tutma
$ in = 'tel.123-12-33';
preg_match_all('!\d+!', $in, $matches);
$out = (int)implode('', $matches[0]);
// $ out = '1231233';
Diğer geçici karşılaştırma sonuçları:
$ 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
{ $i = +"-11"; $i = +"-11"; $i= +"-11"; $i= +"-11"; ... }
. "-11"
Dilin derleme zamanında işin bir kısmını yapmayacağından emin değilseniz, gerçek değeri doğrudan kullanmak da risklidir . Muhtemelen PHP gibi dinamik bir dil için tamam, ancak diğer dillerde formülleri test ediyorsanız gelecekteki referans için bahsedeceğim. $x = "-11"
Test döngüsünden önce bir değişken ayarlamak ve daha sonra kullanmak için daha güvenlidir. Böylece iç kod $i =+$x
.
Bir kıyaslama koştu ve gerçek bir tamsayı elde etmenin en hızlı yolu çıkıyor (mevcut tüm yöntemleri kullanarak)
$foo = (int)+"12.345";
Sadece
$foo = +"12.345";
bir şamandıra döndürür.
(int)"12.345"
mı hızlı ? Yüzde kadar daha hızlı?