Sunday, August 7, 2011

PHP の parse_ini_file 調査

parse_ini_file が遅い気がするので、調べてみた。 以下、サンプルコード。
[192.168.162.128] cat parse_ini.php
<?php
$ret1 = parse_ini_file("sample.ini");
$ret2 = parse_ini_file("sample.ini");

[192.168.162.128] cat sample.ini
[first_section]
one = 1
five = 5
animal = BIRD

[second_section]
path = "/usr/local/bin"
URL = "http://www.example.com/~username"
parsekit にかけてみると、
[192.168.162.128] php -r 'var_dump( parsekit_compile_file("parse_ini.php", $error, PARSEKIT_SIMPLE));'
array(10) {
  [0]=>
  string(37) "ZEND_SEND_VAL UNUSED 'sample.ini' 0x1"
  [1]=>
  string(42) "ZEND_DO_FCALL T(0) 'parse_ini_file' UNUSED"
  [2]=>
  string(26) "ZEND_ASSIGN T(1) T(0) T(0)"
  [3]=>
  string(37) "ZEND_SEND_VAL UNUSED 'sample.ini' 0x1"
  [4]=>
  string(42) "ZEND_DO_FCALL T(2) 'parse_ini_file' UNUSED"
  [5]=>
  string(26) "ZEND_ASSIGN T(3) T(0) T(2)"
  [6]=>
  string(27) "ZEND_RETURN UNUSED 1 UNUSED"
  [7]=>
  string(42) "ZEND_HANDLE_EXCEPTION UNUSED UNUSED UNUSED"
  ["function_table"]=>
  NULL
  ["class_table"]=>
  NULL
}
当たり前かもしれないが、INI ファイルは、opコードに展開されない。つまり、APCではキャッシュしない。
strace してみると、
[192.168.162.128] strace php parse_ini.php 2>&1
open("/home/sikaku/dev/fuwarin/trunk/php/exp/ini/sample.ini", O_RDONLY) = 8
fstat(8, {st_mode=S_IFREG|0664, st_size=130, ...}) = 0
lseek(8, 0, SEEK_CUR)                   = 0
read(8, "[first_section]\none = 1\nfive = 5"..., 8192) = 130
read(8, "", 8192)                       = 0
read(8, "", 8192)                       = 0
close(8)                                = 0
getcwd("/home/sikaku/dev/fuwarin/trunk/php/exp/ini", 4096) = 43
open("/home/sikaku/dev/fuwarin/trunk/php/exp/ini/sample.ini", O_RDONLY) = 8
fstat(8, {st_mode=S_IFREG|0664, st_size=130, ...}) = 0
lseek(8, 0, SEEK_CUR)                   = 0
read(8, "[first_section]\none = 1\nfive = 5"..., 8192) = 130
read(8, "", 8192)                       = 0
read(8, "", 8192)                       = 0
close(8)                                = 0
どうやら、同じファイルにも関わらず毎回パースしてるようだ。