TLDR:更好的是:在每个条件中包含大量类似代码的长if...else
或包含多个检查点的许多较小if...else
语句。
这个问题可能扩展到许多语言,但JavaScript是我立即应用这个想法的地方。
在优化我的JS时,我遇到了一个巨大的if...else
条件。 if
和else
共享一些代码,它们根据条件确定的变量执行某个函数,然后继续执行特定于条件的函数。这是示例:
var w = $(window).width();
if (w > 1024) {
var ww = w/2;
$(".container").width(ww);
foo(); // represents long, in-common set of functions
var imgWidth = ww/3;
$(".container img").width(imgWidth);
} else {
var ww = w/3;
$(".container").width(ww);
foo(); // represents long, in-common set of functions
var imgWidth = ww/4;
$(".container img").width(imgWidth);
}
foo()
表示一个公共中点/检查点函数,它可能与所声明的变量的值无关,但基本上取决于它们的执行。在我的实际代码中,foo()
表示连续发生的许多常见函数,迫使我要么编写一个大的if...else
或许多较小的检查。我的问题是,这是一种更好/更快的方式:
var w = $(window).width();
if (w > 1024) {
var ww = w/2;
$(".container").width(ww);
} else {
var ww = w/3;
$(".container").width(ww);
}
foo(); // represents a checkpoint with long, in-common sets of functions
if (w > 1024) {
var imgWidth = ww/3;
$(".container img).width(imgWidth);
} else {
var imgWidth = ww/4;
$(".container img).width(imgWidth);
}
从视觉上来说,我理解这是两个模型之间的竞争:
我知道如果这些函数变得复杂并且有许多公共检查点,可能会创建一个更大的文件大小,但是这里的性能比一些额外的字节要多得多。什么更好(更快)?
答案 0 :(得分:3)
按性能表示处理器性能?考虑到各种Javascript引擎JIT技术,处理器分支预测等,两种情况之间的差异将不在测量误差范围内。选项B天真地具有更多分支,但这不一定影响性能。设计您的代码以实现人类可读性,并且在您的探查器告诉您代码部分出现问题之前不要担心性能差异。
答案 1 :(得分:2)
您关心的唯一条件是宽度是否为> 1024
,它仅决定除数。你可以摆脱除了一个条件之外的所有条件(在我的例子中是三元组)并且这样做:
var w = $(window).width();
// condition to get the divisor
var divisor = w > 1024 ? 2 : 3;
var ww = ww/divisor;
$(".container").width(ww);
foo();
$(".container img").width(ww/(divisor+1));
答案 2 :(得分:2)
我只是将此作为答案,因为我认为它将超过500个字符。既然你刚刚给出了一个合成的例子,答案是一个很大的“它取决于。”
两个单个大块的好处是执行检查的成本只发生一次,虽然你可以很容易地在开始时将值抛入布尔值然后你的检查可能在更大的成本上下文,只要这不是非常热门的代码(即本身不是经常执行)并且你没有大量的支票。
多次检查的好处可能在于代码维护,特别是您或您的继任者不必担心在两个分支中更新相同的代码。虽然将一些代码分解为单独的函数可能会提供相同的好处。再次,如果这是热门代码,您可能会发现函数调用太昂贵,但我怀疑可能不会。
我会专注于最可维护的内容,我建议这意味着要么进行多次检查,要么将某些代码分解出来。除非是一个问题,否则我不会非常担心性能 - 避免过早优化。
答案 3 :(得分:1)
首先关注可读性/维护。当您有清晰的代码时,识别性能瓶颈会更容易 正如@Rob建议的那样,当前的例子可以简化。如果不是这种情况,您应该考虑if-blocks中的逻辑相似程度。 当它们相似时,你可以使用它们的功能。
var w = $(window).width();
set_container_using_width(w);
foo(); // represents a checkpoint with long, in-common sets of functions
set_img_using_width(w);
代码看起来像一本小说:你想调用foo()并根据w有一些细微差别。
当小说/逻辑真的不同时,小说应该说:我告诉你两个不同的冒险,其中两位英雄都乘坐火车(由foo()实施的火车)。
var w = $(window).width();
if (w > 1024) {
do_some_strange_calls();
foo(); // represents long, in-common set of functions
do_more_strange_calls();
} else {
some_normal_calls();
foo();
some_more_normal_calls();
}
此代码可简化为
var w = $(window).width();
if (w > 1024) {
foo_wrapper_strange_handling();
} else {
foo_wrapper_normal_handling();
}
if-statemant更改时(新要求,if (w>2048)
),您希望在1行更改它。
以下代码不太清楚(难以维护):
var w = $(window).width();
if (w > 1024) {
do_some_strange_calls();
} else {
some_normal_calls();
}
foo(); // represents long, in-common set of functions
if (w > 1024) {
do_more_strange_calls();
} else {
some_more_normal_calls();
}