一个长 If 条件与许多带有检查点的较小条件
One long If condition vs. many smaller conditions with checkpoints
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()
表示一个常见的 midpoint/checkpointfunction,它可能与声明的变量的值无关,但本质上取决于它们的执行。在我的实际代码中,foo()
代表许多连续发生的常见函数,迫使我在整个过程中编写一个庞大的 if...else
或许多较小的检查。我的问题是,这是 better/faster 方式吗:
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);
}
在视觉上,我理解这是这两个模型之间的竞争:
我知道如果这些函数变得复杂并且有许多共同的检查点,它们可能会创建更大的文件大小,但这里的性能远比几个额外的字节更重要。什么更好(更快)?
你唯一关心的条件是宽度是否> 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));
你所说的性能是指处理器性能?考虑到各种 Javascript 引擎 JIT 技术、处理器分支预测等,两种情况之间的差异不会在测量误差范围内。选项 B 天真地拥有更多分支,但这不一定会影响性能。为人类可读性设计您的代码,并且在您的探查器告诉您那部分代码有问题之前,不要担心性能差异。
我只是给出这个答案,因为我认为它会 运行 超过 500 个字符。由于您刚刚给出了一个合成示例,因此答案很大 "it depends."
两个单独的大块的好处是执行检查的成本只发生一次,尽管您可以在开始时轻松地将值放入布尔值,然后您的检查可能没有成本更大的上下文,前提是这不是非常热的代码(即它本身不是不断执行的)并且你没有大量的检查。
多重检查的好处可能在于代码维护,特别是您或您的继任者无需担心在两个分支中更新相同的代码。尽管将一些代码分解为单独的函数可能会提供同样的好处。同样,如果这是热门代码,您可能会发现函数调用的成本太高,但我怀疑可能不会。
我会专注于最易于维护的内容,我建议这意味着多次检查或提取一些代码。除非这是一个问题,否则我不会非常担心性能 - 避免过早优化。
先关注readability/maintenance。当你有清晰的代码时,识别性能瓶颈会更容易。
正如@Rob 建议的那样,可以简化当前示例。如果不是这种情况,您应该考虑 if 块中的逻辑有多少相似。
当它们差不多时,你可以为它们使用一个函数。
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 有一些细微差别。
当 blocks/logic 真的不同时,小说应该说:我告诉你两个不同的冒险,其中两个英雄都乘坐火车(火车由 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 语句发生变化时(新要求,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();
}
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()
表示一个常见的 midpoint/checkpointfunction,它可能与声明的变量的值无关,但本质上取决于它们的执行。在我的实际代码中,foo()
代表许多连续发生的常见函数,迫使我在整个过程中编写一个庞大的 if...else
或许多较小的检查。我的问题是,这是 better/faster 方式吗:
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);
}
在视觉上,我理解这是这两个模型之间的竞争:
我知道如果这些函数变得复杂并且有许多共同的检查点,它们可能会创建更大的文件大小,但这里的性能远比几个额外的字节更重要。什么更好(更快)?
你唯一关心的条件是宽度是否> 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));
你所说的性能是指处理器性能?考虑到各种 Javascript 引擎 JIT 技术、处理器分支预测等,两种情况之间的差异不会在测量误差范围内。选项 B 天真地拥有更多分支,但这不一定会影响性能。为人类可读性设计您的代码,并且在您的探查器告诉您那部分代码有问题之前,不要担心性能差异。
我只是给出这个答案,因为我认为它会 运行 超过 500 个字符。由于您刚刚给出了一个合成示例,因此答案很大 "it depends."
两个单独的大块的好处是执行检查的成本只发生一次,尽管您可以在开始时轻松地将值放入布尔值,然后您的检查可能没有成本更大的上下文,前提是这不是非常热的代码(即它本身不是不断执行的)并且你没有大量的检查。
多重检查的好处可能在于代码维护,特别是您或您的继任者无需担心在两个分支中更新相同的代码。尽管将一些代码分解为单独的函数可能会提供同样的好处。同样,如果这是热门代码,您可能会发现函数调用的成本太高,但我怀疑可能不会。
我会专注于最易于维护的内容,我建议这意味着多次检查或提取一些代码。除非这是一个问题,否则我不会非常担心性能 - 避免过早优化。
先关注readability/maintenance。当你有清晰的代码时,识别性能瓶颈会更容易。
正如@Rob 建议的那样,可以简化当前示例。如果不是这种情况,您应该考虑 if 块中的逻辑有多少相似。
当它们差不多时,你可以为它们使用一个函数。
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 有一些细微差别。
当 blocks/logic 真的不同时,小说应该说:我告诉你两个不同的冒险,其中两个英雄都乘坐火车(火车由 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 语句发生变化时(新要求,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();
}