file_exists() is too slow in PHP. Can anyone suggest a faster alternative?

后端 未结 19 1432
迷失自我
迷失自我 2021-02-05 01:18

When displaying images on our website, we check if the file exists with a call to file_exists(). We fall back to a dummy image if the file was missing.

Howe

19条回答
  •  闹比i
    闹比i (楼主)
    2021-02-05 01:36

    Benchmarks with PHP 5.6:

    Existing File:

    0.0012969970 : stream_resolve_include_path + include  
    0.0013520717 : file_exists + include  
    0.0013728141 : @include  
    

    Invalid File:

    0.0000281333 : file_exists + include  
    0.0000319480 : stream_resolve_include_path + include  
    0.0001471042 : @include  
    

    Invalid Folder:

    0.0000281333 : file_exists + include  
    0.0000360012 : stream_resolve_include_path + include  
    0.0001239776 : @include  
    

    Code:

    // microtime(true) is less accurate.
    function microtime_as_num($microtime){
      $time = array_sum(explode(' ', $microtime));
      return $time;
    }
    
    function test_error_suppression_include ($file) {
      $x = 0;
      $x = @include($file);
      return $x;
    }
    
    function test_file_exists_include($file) {
      $x = 0;
      $x = file_exists($file);
      if ($x === true) {
        include $file;
      }
      return $x;
    }
    
    function test_stream_resolve_include_path_include($file) {
      $x = 0;
      $x = stream_resolve_include_path($file);
      if ($x !== false) {
        include $file;
      }
      return $x;
    }
    
    function run_test($file, $test_name) {
      echo $test_name . ":\n";
      echo str_repeat('=',strlen($test_name) + 1) . "\n";
    
      $results = array();
      $dec = 10000000000; // digit precision as a multiplier
    
      $i = 0;
      $j = 0;
      $time_start = 0;
      $time_end = 0;
      $x = -1;
      $time = 0;
    
      $time_start = microtime();
      $x= test_error_suppression_include($file);
      $time_end = microtime();
      $time = microtime_as_num($time_end) - microtime_as_num($time_start);
    
      $results[$time*$dec] = '@include';
    
      $i = 0;
      $j = 0;
      $time_start = 0;
      $time_end = 0;
      $x = -1;
      $time = 0;
    
      $time_start = microtime();
      $x= test_stream_resolve_include_path_include($file);
      $time_end = microtime();
      $time = microtime_as_num($time_end) - microtime_as_num($time_start);
    
      $results[$time * $dec] = 'stream_resolve_include_path + include';
    
      $i = 0;
      $j = 0;
      $time_start = 0;
      $time_end = 0;
      $x = -1;
      $time = 0;
    
      $time_start = microtime();
      $x= test_file_exists_include($file);
      $time_end = microtime();
      $time = microtime_as_num($time_end) - microtime_as_num($time_start);
    
      $results[$time * $dec ] = 'file_exists + include';
    
      ksort($results, SORT_NUMERIC);
    
      foreach($results as $seconds => $test) {
        echo number_format($seconds/$dec,10) . ' : ' . $test . "\n";
      }
      echo "\n\n";
    }
    
    run_test($argv[1],$argv[2]);
    

    Command line Execution:

    php test.php '/path/to/existing_but_empty_file.php' 'Existing File'  
    php test.php '/path/to/non_existing_file.php' 'Invalid File'  
    php test.php '/path/invalid/non_existing_file.php' 'Invalid Folder'  
    

提交回复
热议问题