최근 json 파일을 읽어와 데이터 처리를 하면서 궁금증이 생겼다. 

파일읽기 함수는 여러가지가 있는데 이중 속도차이가 많이 날까라는 의문이였다. 

 

나같은 경우 파일 내용을 읽을 시 file_get_contents  와 include  를 많이 사용했는데  검색하다보니 

file_get_contents 가 더 빠르다는 글이 있어 몇가지 함수를 더 추가해서 테스트를 해보았다. 

 

테스트의 경우 아래의 함수를 기준으로 하였다. 

 

  • fgets 
  • fread
  • file
  • file_get_contents
  • include

 

위의 함수중 file 함수같은 경우 line 단위로 읽어와서 배열에 담기 때문에 막상 출력할려면 상당히 느리고

파일읽기 성능 테스트와는 그렇게 맞지 않긴 하지만 그래도 한번 넣어보았다. 

 

처음 테스트 결과는 이렇다. 

 

1위: include, 0.000071초 걸림
2위: fread, 0.000124초 걸림
3위: file_get_contents, 0.000134초 걸림
4위: file, 0.000415초 걸림
5위: fgets, 0.000537초 걸림


총 걸린시간: 0.001281

 

역시나 include 가 빠르긴 했으나 맨 처음 실행했을때는 그렇게 성능이 좋지만은 않았다. 

그렇게 테스트를 몇번 더 해보고 난뒤 아무래도 file_get_contents 속도가 빠른 경우가 있지 않을까 하여

여러 방법으로 테스트를 해보았고 그 경우의 수를 찾게 되었다. 

 

그건 바로  읽을 데이터 파일의 크기였다.

 

처음 테스트했던 데이터의 경우 5천줄이 넘지 않는 데이터였는데, 그 후 10만줄이 넘는 데이터로 

테스트를 해보니 확실 히 차이가 보이기 시작했다. 

 

10만줄로 테스트한 결과는 아래와 같았다. 

 

1위: file_get_contents, 0.024729초 걸림
2위: fread, 0.029698초 걸림
3위: include, 0.049606초 걸림
4위: file, 0.126652초 걸림
5위: fgets, 0.143493초 걸림


총 걸린시간: 0.374178

 

include 가 1위에서 3위로 밀린것을 확인가능한데 사실상 캐싱 되기전에는 5위였다. 

 

결론적으로는 파일 내용을 읽을때는 file_get_contents 를 사용하는게 좋다. 

include 같은 경우 아무래도 PHP 소스 내용이 있을 경우 조건처리가 되기때문에 

파일 내용 읽기로는 맞지 않다. 

 

그동안은 아무생각없이 include 로 ob_start 함수와 조합해서 파일을 막 읽어 들였는데 내용만 읽을 때는 

include 는 절대 사용하면 안되겠다는 생각을 가지게 되었다.

 

아래는 이번에 테스트하면서 만든 소스인데 결과가 궁금한 경우 아래 소스를 가지고 

직접 테스트 해보길 바란다. 

 

<?php 
function get_time() { $t=explode(' ',microtime()); return (float)$t[0]+(float)$t[1]; }
function get_exec($filename , $type, $count = 10){
    $start = get_time();

    
    for($i=0;$i<$count;$i++){
        $contents = '';
        switch($type){
            case "fgets":
                $handle = fopen($filename, "r");
                while (($buffer = fgets($handle, 4096)) !== false) { $contents .= $buffer;}
                fclose($handle);
            break;

            case "fread":
                $handle = fopen($filename, "r");
                $contents = fread($handle, filesize($filename));
                fclose($handle);
            break;

            case "file":
                $handle = file($filename);
                foreach($handle as $v){  $contents .= $v; }
            break;

            case "file_get_contents":
                $contents = file_get_contents($filename);
            break;

            case "include":
                ob_start();
                include $filename;
                $contents = ob_get_clean();                
            break;                        

        }
    }

    $end = get_time();
    $time = $end - $start;
    return $time;
}
    

$test = array('fgets','fread','file','file_get_contents','include'); // 테스트 정의
$result = array(); // 결과

$filename = dirname(__FILE__)."/test.txt"; // 읽을 파일
$count = 1;  // 실행 횟수  
foreach($test as $k=>$v){
    $time = get_exec($filename,$v,$count);
    $result[$v]  = $time;
    unset($time);
}
asort($result);
$rank = 1; // 랭킹 표시용도
foreach($result as $k=>$v){
    echo ($rank++).'위: '.$k.', '.number_format($v,6).'초 걸림';
    echo '<hr>';
}
echo '총 걸린시간: '.number_format(array_sum($result),6);