settype () vs *val () 함수로 가장 빠른 PHP 유형 Jugling?
-
06-07-2019 - |
문제
나는 값이 I Type I 필요한 그것은. 나는 둘 다 같은 일을하는 두 줄의 코드를 만들었습니다. 문제는 벤치 마크를 기반으로 가장 빠른지 알아낼 수 없다는 것입니다.
(is_scalar($value) ? intval($value) : 0);
settype($value, 'integer');
다음 테스트 코드를 만들었지 만 내 PC (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';
어쨌든, 나는이 방법 중 어느 것이 더 빠르게 작동 할뿐만 아니라, 이상한 결과를 얻을 수 있는지에 대해 더 많이 누락 될 수 있는지 궁금합니다. 또 다른 것은 이것이 ints로 성공을 가득 채우는 것입니다. 그러면 문자열과 부유물과 같은 다른 유형도 작동해야한다는 것입니다.
:업데이트:
방금이 방법을 플로트 유형에 대해 테스트 한 결과 settype ()가 느린 (.28 초) 대 플로트 val () (.21 sec)임을 발견했습니다. 따라서이 질문에 대한 답변은 int 유형에만 유효 할 수 있습니다.
//Float
(is_scalar($value) ? floatval($value) : 0);
settype($value, 'float');
해결책
이 특정 사례의 속도 차이는 실제로 중요하다고 간주 될 수 없기 때문에 순수한 이론적 관심을 요구하는 것 같습니다.
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
보시다시피, 두 기능 모두 동일한 convert_to_long 루틴을 사용합니다 (이는 라이브러리 호출 strtol로 줄어 듭니다). settype에는 두 번째 인수를 유형 문자열과 비교하는 (작은) 오버 헤드가 포함되므로 약간 느려져야합니다.
가장 빠른 방법은 (int) 캐스트를 사용하는 것입니다. 함수 호출 Opcode가 포함되지 않지만 VM에 의해 직접 실행됩니다.
다른 팁
간단한 벤치 마크를 봅시다 :
<?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 비트 우분투에 대한 나의 결과 :
intval: 0.47533583641052 sec.
(int): 0.19618892669678 sec.
settype: 0.51951289176941 sec.
긴 정수에서 그림은 비슷합니다. 그래서 (int)는 최고이지만 settype () 대신 intval ()을 사용해야 할 실제 이유는 없습니다.
Bazillion 값을 테스트 할 계획이 없다면 실제 속도 차이는 없어야합니다. 존재하는 것은 너무 작아서 실제로 아무런 영향을 미치지 않습니다.
직접 (유형) 캐스팅이 가장 빠릅니다. 여기에 내가 사용하는 코드는 다음과 같습니다.
(is_scalar($int) && is_numeric($int) ? (int) $int : 0)