【问题标题】:Is file_get_contents slower than include?file_get_contents 是否比包含慢?
【发布时间】:2011-01-20 15:52:23
【问题描述】:

有一个我经常使用的 php 5 库的文件缓存系统。 当发出请求时,我会检查缓存文件,如果有,我会渲染它并退出。

$contents = file_get_contents( self::_cacheFile() );
echo $contents;
exit();     

我必须做 file_get_contents 而不是仅仅包含因为缓存的 xml 文件带有讨厌的

`<?xml version="1.0"?>` 

有没有更好的方法在不触发短标签的情况下提取我的缓存文件?

【问题讨论】:

  • 然后人家说短标签没问题……
  • 是的,我讨厌短标签,就像上面的例子一样,似乎很容易意外触发 php。
  • 这对二进制存储大喊大叫。压缩文件进行存储并将它们解压缩到内存中怎么样?或者,如果您正在缓存整个响应,发送压缩副本?这将避免短标签。就个人而言,每当我访问 php.ini 时,我都会关闭短标签。

标签: php xml caching


【解决方案1】:

file_get_contentsinclude 不做同样的事情:

  • file_get_contents 读取文件内容,并以字符串形式返回
  • include 将执行文件的内容。

关于速度,如果没有操作码缓存,我想file_get_contents 理论上应该更快,因为它的计算量更少(无需编译/执行代码)

不过,最重要的可能是您正在尝试做的事情:如果您只想读取文件,则应该使用file_get_contents

【讨论】:

    【解决方案2】:

    由于include 将评估文件的内容,例如通过 PHP 解释器运行并使用 include_path 查找文件,我会说 include 较慢。 file_get_contents 只会将文件的内容视为字符串。更少的开销,更快的速度。

    来自manual page

    file_get_contents() 是将文件内容读入字符串的首选方法。如果您的操作系统支持,它将使用内存映射技术来提高性能。

    但是,如果您是在输出文件之后,而不是将其转换为字符串,readfile() 甚至比file_get_contents 快一点。鉴于include'ing 也会输出任何非 PHP 内容,这很可能是我猜测的结果。

    在我的台式机上修改了基准:

    $start1 = microtime(1);
    for($i=0; $i<100000; $i++) {
        include 'log.txt';
    }
    $end1 = microtime(1) - $start1;
    

    $start2 = microtime(1);
    for($i=0; $i<100000; $i++) {
        echo file_get_contents('log.txt');
    }
    $end2 = microtime(1) - $start2;
    

    $start3 = microtime(1);
    for($i=0; $i<100000; $i++) {
        readfile('log.txt');
    }
    $end3 = microtime(1) - $start3;
    

    结果

    echo PHP_EOL, $end1, // 137.577358961
         PHP_EOL, $end2, // 136.229552984
         PHP_EOL, $end3; // 136.849179029
    

    【讨论】:

    • 10 年后:include:0.05 秒,file_get_contents:1.06 秒。我猜这些天 PHP 缓存包含文件的效率稍微高了一点。
    【解决方案3】:

    没有什么能胜过(制作精良的)基准(这比看起来更难,我可能忽略了一些东西)。仍然因为两者都是在相同的条件下制造的,所以它们应该用作量尺。

    test.txt 是一个 12kB、876 行的文本文件:

    vinko@parrot:~$ ls -la test.txt ; wc -l test.txt
    -rw-r--r-- 1 vinko vinko 12264 2010-02-24 19:08 test.txt
    876 test.txt
    

    file_get_contents.php:

    vinko@parrot:~$ more file_get_contents.php
    <?php
    echo file_get_contents("test.txt");
    ?>
    

    include.php

    vinko@parrot:~$ more include.php
    <?php
    include("test.txt");
    ?>
    

    readfile.php

    vinko@parrot:~$ more readfile.php
    <?php
    readfile("test.txt");
    ?>
    

    因此,我们对每个迭代执行 10000 次进行计时:

    vinko@parrot:~$ time for i in `seq 10000`; do php file_get_contents.php >/dev/null; done
    
    real    3m57.895s
    user    2m35.380s
    sys     1m15.080s
    
    vinko@parrot:~$ time for i in `seq 10000`; do php include.php >/dev/null; done
    
    real    3m57.919s
    user    2m37.040s
    sys     1m16.780s
    
    vinko@parrot:~$ time for i in `seq 10000`; do php readfile.php >/dev/null; done 
    real    3m57.620s
    user    2m38.400s
    sys     1m14.100s
    

    结论:对于带有 Suhosin 补丁的 PHP 5.2.4 上的 12 kB 文本文件,这三个文件实际上是等效的。

    【讨论】:

    • 应该是echo $contents;,没有()。同样readfile 直接写入输出缓冲区并返回一个整数,因此无需回显。只需致电readfile。你也不需要exit 调用。
    • @Gordon:谢谢,更改了脚本并重新测试。更平等:)
    【解决方案4】:

    感谢您的提示,对于那些好奇的人

    readfile();
    <!-- dynamic page rendered in 0.133193016052 seconds.-->
    <!-- static page rendered in 0.00292587280273 seconds.-->
    

    对比

    file_get_contents();
    <!-- dynamic page rendered in 0.133193016052 seconds.-->
    <!-- static page rendered in 0.00303602218628 seconds.-->
    

    对比

    include();
    <!-- dynamic page rendered in 0.133193016052 seconds.-->
    <!-- static page rendered in 0.00348496437073 seconds.-->
    

    【讨论】:

    • 单次执行不足以进行基准测试,您必须进行大量迭代
    • 静态页面的响应时间延长 10%。现在,当您打开操作码缓存时会发生什么? +1 用于研究。
    【解决方案5】:

    如果您只想输出文件内容,您应该使用 readfile()。这比 file_get_contents() 更快且占用更少的内存

    【讨论】:

      【解决方案6】:

      file_get_contents 将是检索缓存文件的最快方法,原因如下:

      1. 它不对其加载的数据执行任何处理(解析 PHP 代码、处理换行符等)
      2. 它使用优化技术尽可能快地加载文件(一个是内存映射文件)。

      【讨论】:

        猜你喜欢
        • 2012-02-04
        • 2015-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-03
        • 2015-04-08
        • 2012-08-19
        • 2014-01-07
        相关资源
        最近更新 更多