PHP短路评估(好/坏?)
作者:互联网
这是一个一般性的问题,但是为了解释它,我将使用一个特定的示例.
我有一个加载文档的功能.如果该文档不存在,它将创建该文档;如果该文档存在,则将其转换为JSON数组.我始终希望此函数返回某种数组,无论json_decode()是否存在问题或文件是否不存在.目前我正在这样做…
function load($file) {
if( ! file_exists($file)) {
$handle = fopen($file, 'w');
fclose($handle);
}
$raw = file_get_contents($file);
$contents = json_decode($raw, TRUE);
return( ! $contents ? array() : $contents);
//cant use ternary shorthand "?:" in PHP 5.2, otherwise this would be shorter
}
现在,上面的代码没有任何问题(至少我不认为有问题,并且工作正常).但是,我一直在寻找改进代码并压缩代码同时又使代码清晰易读的方法.由于看起来效率很低,所以那个return语句一直困扰着我.所以今天我开始思考,发生了一些事情.我记得曾经看过mysql教程,这些教程对connect()或die()起到了作用;所以我想,为什么不使用json_decode()或array();?这甚至行得通吗?所以我重写了函数以找出…
function load($file) {
if( ! file_exists($file)) {
$handle = fopen($file, 'w');
fclose($handle);
}
$raw = file_get_contents($file);
return json_decode($raw, TRUE) or array();
}
看起来,甚至读起来也足够愉快.接下来是我的下一个问题.这是好习惯吗?我了解,但还有其他人吗?它真的有效吗,或者这是一个结局令人满意的错误?我四处张望,发现我要问的是短路评估而不是错误.很高兴知道.我使用了这个新词来完善搜索范围,并提出了更多材料.
我发现的几乎所有内容都没有,而且我询问的总是使用MySQL连接的方式涉及使用短路.现在,我知道大多数人都反对使用or die()术语,但这仅仅是因为这是一种处理错误的优雅方法.对于我要问的方法来说,这不是问题,因为我不是在寻求使用或die().还有其他原因不使用此功能吗? Wikipedia似乎是这样认为的,但是仅涉及C.我知道PHP是用C编写的,因此,这绝对是相关的信息.但是这个问题在PHP编译中是否已解决?如果不是,它是否像Wikipedia那样糟糕?
这是维基百科的片段.
Wikipedia-“短路可能导致现代处理器上的分支预测出错,并极大地降低性能(一个显着的例子是在射线追踪中使用高度对齐的具有轴对齐框交点代码的射线)[需要澄清].某些编译器可以检测到这种情况并发出更快的代码,但由于可能违反C标准,并非总是可能.高度优化的代码应使用其他方式来执行此操作(例如,手动使用汇编代码)”
你们怎么想
编辑
我在另一个论坛上进行了投票,并在那获得了一些不错的结果.普遍的共识似乎是,这种形式的变量赋值虽然有效,却不是首选,甚至在现实世界中可能被认为是不好的形式.我将继续保持关注,如果有任何新变化,我将进行更新.谢谢Corbin和Matt的投入,尤其是Corbin整理了几件事.如果您有兴趣,请访问论坛帖子的链接Here.
解决方法:
您有几个不同的问题,所以我将尽力解决.
遗漏的分支预测:除非您使用C或汇编语言编写,否则不必担心.在PHP中,您与硬件相距甚远,因此考虑分支预测将无济于事.无论哪种方式,这都是非常微小的优化,尤其是在进行大量字符串解析的函数中.
Is there any other reason not to use this? Wikipedia seems to think so, but only in reference to C. I know PHP is written in C, so that is definitely pertinent information.
PHP可能会将其解析为不同的执行结构.除非您计划运行此功能数百万次,或者您知道这是一个瓶颈,否则我不会为此担心.在2012年,我发现使用或短路不会造成十亿分之一秒的差异.
至于格式,我发现$a或$b很难看.我的想法并不像在if子句中那样理解短路.
if (a() || b())
我完全清楚,只有当a()的计算结果不为true时,b()才会执行.
然而:
return a() or b();
对我来说不一样.
显然,这只是一种意见,但是我将提供两种选择方式(我认为这很清楚):
function load($file) {
if (!file_exists($file)) {
touch($file);
return array();
}
$raw = file_get_contents($file);
$contents = json_decode($raw, true);
if (is_array($contents)) {
return $contents;
} else {
return array();
}
}
如果您不关心文件是否真正创建,则可以更进一步:
function load($file) {
$raw = file_get_contents($file);
if ($raw !== false) {
$contents = json_decode($raw, true);
if ($contents !== null) {
return $contents;
}
}
return array();
}
我猜这些代码片段确实取决于个人喜好.第二个片段可能是我要使用的片段.关键路径可能会更清晰一些,但我觉得它保持简洁而不牺牲可理解性.
编辑:如果您是一种功能返回1的人,则以下内容可能更可取:
function load($file) {
$contents = array();
$raw = file_get_contents($file);
if ($raw !== false) {
$contents = json_decode($raw, true);
if ($contents === null) {
$contents = array();
}
}
return $contents;
}
标签:short-circuiting,php 来源: https://codeday.me/bug/20191201/2080186.html