がるの健忘録

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

実験:issetとarray_key_existsはどっちが早い?

ちと別件で書く必要があったので、ついでに実験。
具体的には「(第一種)ホワイトリスト」でのチェックを使った、パストラバーサル防御のコードなんだけど。


ちなみに先に一つ。
「検索対象を配列の値に入れてin_array」は下策もいい所なので、いっちょまえの大人がやっていいコードではありません。
「hash配列」の前提になるハッシュ法とかに思いをはせつつ、最低でも「検索対象はkeyに入れる」くらいの嗜みを持ちましょう。


で…本音ぶっちゃけるとですね「existsのスペルがなんでか覚えられない」のよおいちゃん(苦笑
なのでそーゆー理由でissetを乱用するのですが、実際のところ「ど〜なんだろうなぁ?」ってのがあって、ちと調査。

<?php

$awk = array();
for($i = 0; $i < 200000; $i ++) {
  $awk[] = $i;
}

$t = microtime(true);

for($i = 0; $i < 10000; $i ++) {
    $key = mt_rand(0, 199999);
    $j = array_key_exists($key, $awk);
    //$j = isset( $awl[$key] );
}


$t = microtime(true) - $t;
var_dump($t);

PHP5系

[gallu@localhost ~]$ vi t.php
[gallu@localhost ~]$ php t.php
float(0.020144939422607)
[gallu@localhost ~]$ php t.php
float(0.020148038864136)
[gallu@localhost ~]$ php t.php
float(0.019990921020508)
[gallu@localhost ~]$ php t.php
float(0.020182847976685)
[gallu@localhost ~]$ php t.php
float(0.020066022872925)

PHP7系

[gallu@www4320uj ~]$ php t.php
float(0.0041100978851318)
[gallu@www4320uj ~]$ php t.php
float(0.0051558017730713)
[gallu@www4320uj ~]$ php t.php
float(0.0036821365356445)
[gallu@www4320uj ~]$ php t.php
float(0.0027759075164795)
[gallu@www4320uj ~]$ php t.php
float(0.0042760372161865)

<?php

$awk = array();
for($i = 0; $i < 200000; $i ++) {
  $awk[] = $i;
}

$t = microtime(true);

for($i = 0; $i < 10000; $i ++) {
    $key = mt_rand(0, 199999);
    //$j = array_key_exists($key, $awk);
    $j = isset( $awl[$key] );
}


$t = microtime(true) - $t;
var_dump($t);

PHP5系

[gallu@localhost ~]$ php t.php
float(0.011642932891846)
[gallu@localhost ~]$ php t.php
float(0.011620044708252)
[gallu@localhost ~]$ php t.php
float(0.011649131774902)
[gallu@localhost ~]$ php t.php
float(0.011752128601074)
[gallu@localhost ~]$ php t.php
float(0.011624813079834)

PHP7系

[gallu@www4320uj ~]$ php t.php
float(0.0024490356445312)
[gallu@www4320uj ~]$ php t.php
float(0.0030300617218018)
[gallu@www4320uj ~]$ php t.php
float(0.0031118392944336)
[gallu@www4320uj ~]$ php t.php
float(0.002769947052002)
[gallu@www4320uj ~]$ php t.php
float(0.0029900074005127)


ふむぅ…PHP7だと「どっちも差なし」で、PHP5だとむしろissetのほうが優位なのか。
もしかして「issetは本当は言語構造」ってあたりが関連しているのかしらん?


まぁ、これで心置きなく「isset使う」って選択肢が持てるからいいやw