TL; DR

执行file_exists或检查@include的返回值是否更快(即抑制错误)?

在这种情况下,您可能会假设我使用的是绝对路径,而不是依赖于include_path解析。

精心制作的版本

有了框架和/或软件在引导过程中拥有的所有条件代码,我开始想知道最快的失败方法而不牺牲优美性。我有一个特定的用例,这种思想进入了我的脑海,即包括一个不一定存在的配置文件。

无论如何,这两个操作都会进行统计,因此无法避免磁盘访问。后一种选择的另一个好处是,成功读取并解析了文件,因此在我看来,这已经是一笔不小的数目了。

这确实是一个极端的微优化,尤其是在我只涉及一个文件的情况下,但是这个问题仍然困扰着我,我自己也不知道如何正确地对此进行测试。

接受后进行蛮力测试

得到正确答案后,我进行了一些蛮力测试。我以前不想这样做,因为我想从现场获得明智的答案。另外,我也不想仅仅基于蛮力测试,因为我完全不确定这是否是测试的正确方法。 (实际上,我可以肯定不是。)

我所做的是运行以下代码段:

<?php
$rounds = 1e6;
$start = microtime(true);

while ($rounds--) {
    @include "i-dont-exist";
    clearstatcache();
}

echo microtime(true) - $start, PHP_EOL;


...和...

<?php
$rounds = 1e6;
$start = microtime(true);

while ($rounds--) {
    file_exists("i-dont-exist");
    clearstatcache();
}

echo microtime(true) - $start, PHP_EOL;


...和...

<?php
$rounds = 1e6;
$start = microtime(true);

while ($rounds--) {
    @include "i-exist";
    clearstatcache();
}

echo microtime(true) - $start, PHP_EOL;


...和...

<?php
$rounds = 1e6;
$start = microtime(true);

while ($rounds--) {
    if (file_exists("i-exist")) @include "i-exist";
    clearstatcache();
}

echo microtime(true) - $start, PHP_EOL;


结果是:

不存在的文件

@include:27.090675830841
file_exists:1.0596489906311

现有文件

@include:19.758506059647
file_exists + include:22.083800077438

我们可以从中得出什么结论?好吧,至少根据the answer by @goldencrater中提供的链接,抑制错误的代价很高。

总的来说,我认为抑制错误也是愚蠢的-除非是明智的选择,否则我认为我的用例可以验证这一标准。

如果在包含一个包含文件后失败了,那么在我看来,抑制包含错误是合理的,因为仅根据失败的请求推断失败的代价。 (即不会抑制并忽略该错误。)对失败的请求投入沉重的成本要比对每个请求花费少量成本要差得多。

最佳答案

即使错误抑制(@)本身具有巨大的开销,但消除file_exists调用总是更快。

Smarty模板引擎背后的家伙将他们的整个代码库更改为使用@而不是file_exists(和类似的)检查,最终大大提高了速度。这是其中一位作者的博客文章,详细介绍了更改:http://blog.rodneyrehm.de/archives/12-Improving-Disk-IO-in-PHP-Apps.html

关于php - File_exists vs抑制的include,这是PHP失败的更快方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13705179/

10-11 04:33