File_exists相对于被抑制的include,这是PHP失败的更快方法 [英] File_exists vs suppressed include, which is the faster way to fail in PHP

查看:103
本文介绍了File_exists相对于被抑制的include,这是PHP失败的更快方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR

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

Is it faster to do a file_exists, or checking the return value from @include (i.e. suppressing errors)?

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

In this context, you may assume I'm using absolute paths and not relying on include_path resolving.

精心制作的版本

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

With all the conditional code that frameworks and/or software has in their bootstrap process, I started wondering about the fastest way to fail, without sacrificing gracefulness. I have a specific use case in which this thought entered my mind, namely including a config file which doesn't necessarily exist.

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

Both operations do a stat anyway, so there's no way to avoid disk access. The latter option has the added benefit of having read and parsed the file when it succeeds, so in my mind that's already quite a big bonus.

这确实是一个极端的微优化,尤其是在我只涉及一个文件的情况下,但是这个问题仍然让我感到厌烦,我不知道如何自己进行适当的测试.

This is really an extreme micro-optimization, especially in my case where it's only about one file, but the question still bugs me to death and I don't know how to test this properly myself.

接受后的蛮力测试

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

After I got a proper answer, I did some brute force testing. I didn't want to do this before, since I wanted informed answers from the field. Also, I didn't want to base this solely on my brute force testing, because I'm not at all sure this is the proper way to test this. (Actually, I'm quite certain it isn't.)

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

What I did was run the following code snippets:

<?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: 27.090675830841
file_exists: 1.0596489906311

现有文件

@include:19.758506059647
file_exists + include:22.083800077438

@include: 19.758506059647
file_exists + include: 22.083800077438

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

What can we conclude from this? Well, at least, as per the links provided in the answer by @goldencrater, suppressing errors is expensive.

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

In general, I believe suppressing errors is also stupid - unless it's an informed choice, a criteria which I think my use case validates.

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

If you're going to fail after including a including a file fails, in my mind suppressing the error from include is justifiable, since the cost of failing is only inferred on a failing request. (I.e. the error isn't suppressed and ignored.) Putting a heavy cost on a failing request is much less worse than putting a small cost on every request.

推荐答案

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

Even though error supression (@) has a huge overhead in itself, eliminating the file_exists call is always faster.

Smarty模板引擎背后的家伙将他们的整个代码库更改为使用@而不是file_exists(和类似的)检查,并最终大大提高了速度.这是其中一位作者的博客,详细介绍了更改:

The guys behind the Smarty templating engine changed their entire codebase to use @ instead of file_exists (and similar) checks and ended up with a major speed increase. Here's a blog post from one of the authors detailing the change: http://blog.rodneyrehm.de/archives/12-Improving-Disk-IO-in-PHP-Apps.html .

这篇关于File_exists相对于被抑制的include,这是PHP失败的更快方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆