通常当我想检查一个条件或另一个条件是否为真时,我会编写如下代码:
if (i == 5 || j == 3) { // Do whatever here. }
是否有一个整洁/高性能的方法来避免使用 OR 运算符检查不同条件的编码风格陷阱?
通常当我想检查一个条件或另一个条件是否为真时,我会编写如下代码:
if (i == 5 || j == 3) { // Do whatever here. }
是否有一个整洁/高性能的方法来避免使用 OR 运算符检查不同条件的编码风格陷阱?
不。您想知道一个陈述 OR 另一个是否为真……因此您使用 OR 运算符。这不是陷阱……这就是逻辑的运作方式。
不过,真的没有理由担心性能。两次检查不会有任何伤害。此外,在支持短路运算符的语言中,语句将在第一个计算结果为 true 的表达式之后完成执行。
既然您提到“性能”,我假设您可能没有意识到这||
是短路,这意味着它会在它的任何部分为真时立即停止,因此它不会评估超过它必须.
有关更多信息,请参阅文档。
|| 运算符是高效的,因为它是 OrElse ,这意味着如果第一个条件为真,则不会评估第二个条件,只有在第一个条件为假时才会评估它。&& (AndAlso) 运算符的相同之处在于,仅当第一个条件为真时才会评估第二个条件。
通过编码风格陷阱,您的意思是(我们都已经看到)您最终只是添加到if
语句中吗?所以你最终会得到:
if ( a == 2 || a == 3 || a == 5 || a == 14 ) // etc.
随着更多条件的添加,支持。例如,假设这a
是一个消息类型或可交易商品,随着支持的消息类型或商品越来越多,代码变得越来越复杂。
此外,此检查可能会在各处重复,因为不一定了解原始内容或没有时间重构的程序员只是试图在不理解的情况下复制此条件。
在不知不觉中,代码 (a) 非常难以阅读和理解(i == 5 || j == 3
实际上是什么意思?),并且 (b) 因为您在代码中添加了条件,所以测试变得更加困难。
如果可能的话,将这个逻辑放在一个可以记录的地方会更好:
inline bool isEngineStarted() { return i == 5 || j == 3; }
if ( isEngineStarted() ) // etc.,
这将是我的首要考虑 - 使其以易于理解且易于维护的方式工作。
就性能而言,您可能想要查看的一个建议是,如果您在相对较小的范围内有几个不同的值可供比较,您可能会发现布尔值的稀疏向量可能会更好,因为理论上,查找成本无论替代值的数量如何(即O(1)而不是O(N))都相同所以如果你有,说:
for ( int a = 0; a < 1000000000; ++a )
{
int c = a % 16;
if ( c == 2 || c == 3 || c == 5 || c == 14 ) b++;
}
您可能会发现它的工作速度更快,如下所示:
int b = 0;
bool sp[] = { false, false, true, true, false, true, false, false, false, false, false, false, false, false, true, false };
for ( int a = 0; a < 1000000000; ++a )
{
int c = a % 16;
if ( sp[ c ] ) b++;
}
我不得不说,当我尝试这个时,令人惊讶的是,第一个工作得更快!我很想知道是否有人可以提出原因。
如果您真的想避免使用逻辑 OR,并且如果您想检测单个变量是否是多个可能值之一(您在示例中没有这样做 - 您有两个),那么您可以做一些事情像这样:
class Program
{
static void Main(string[] args)
{
if (2.ContainedIn(1, 2, 3))
{
Console.WriteLine("found it!");
}
}
}
public static class ExtensionMethods
{
public static bool ContainedIn(this int val, params int[] vals)
{
return vals.Contains(val);
}
}
我不确定我对此有何感想;我不认为它可以节省很多,但可能会有所帮助。