2

TL;博士

file_exists执行 a或检查返回值@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

我们可以从中得出什么结论?好吧,至少,根据@goldencrater 答案中提供的链接,抑制错误是昂贵的。

一般来说,我认为抑制错误也是愚蠢的——除非它是一个明智的选择,一个我认为我的用例验证的标准。

如果在包含文件失败后您将失败,在我看来,从包含中抑制错误是合理的,因为失败的成本只能根据失败的请求来推断。(即错误不会被抑制和忽略。)在失败的请求上付出沉重的代价比在每个请求上付出小代价要糟糕得多。

4

1 回答 1

2

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

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

于 2012-12-04T15:02:54.673 回答