避免使用数组分支
Avoiding branching using arrays
假设我有一个非常简单的函数,叫做 foo
。 Foo 可以 return 两个值,我将使用 x
和 y
作为任意占位符变量。
我是这样定义的:
int foo(bool expression)
{
static const int x = ..., y = ...;
if(expression)
return x;
else
return y;
}
这显然一个分支语句
我在想做类似下面的事情可以删除任何分支:
int foo(bool expression)
{
static const int array[] = {x, y};
return array[expression];
}
但是我不确定,通过使用 C 数组,它是否仍然会产生分支,是吗? C++ std::
数组或向量会导致分支吗?
尝试从数组中读取是否值得,还是浪费内存和执行速度?
最后,如果 expression
包含一个逻辑表达式,例如 &&
,这是否意味着它仍然会分支?
至于 condition
依靠布尔值来知道下一步要做什么,那么它肯定是分支。按理说代码本身需要等待和分支来决定访问数组中的哪个元素和return.
根据相同的概念,&&
或任何其他逻辑运算符都表示分支。
这个问题很复杂,因为在一种情况下你显示的是 bool
expression
,而在另一种情况下你显示的是 int
condition
。
如果您的表达式自然计算为 int
,则使用此 int
从数组中选取一项将不会涉及任何分支。如果表达式求值的最自然类型是 bool
,那么您需要将其转换为 int
,并且此转换可能在内部涉及分支,因此您可能不会获得任何事物。我说 "probably" 因为很大程度上取决于编译器和底层 CPU 指令集,所以除非您让编译器生成反汇编并检查反汇编,否则您不会知道。
话虽如此,我要补充一点,您消除分支的追求是徒劳的。分支本身并没有什么坏处,也不会表现得很差。诚然,最好是消除分支,但前提是这样做微不足道。如果为了消除分支,您引入了一个原本不会有的数组,那么您增加的开销可能比节省的开销多一个数量级。如果引入向量而不是数组,则引入的开销可能是数组的两倍。所以,我对此的建议是:不要担心分支。
假设我有一个非常简单的函数,叫做 foo
。 Foo 可以 return 两个值,我将使用 x
和 y
作为任意占位符变量。
我是这样定义的:
int foo(bool expression)
{
static const int x = ..., y = ...;
if(expression)
return x;
else
return y;
}
这显然一个分支语句
我在想做类似下面的事情可以删除任何分支:
int foo(bool expression)
{
static const int array[] = {x, y};
return array[expression];
}
但是我不确定,通过使用 C 数组,它是否仍然会产生分支,是吗? C++ std::
数组或向量会导致分支吗?
尝试从数组中读取是否值得,还是浪费内存和执行速度?
最后,如果 expression
包含一个逻辑表达式,例如 &&
,这是否意味着它仍然会分支?
至于 condition
依靠布尔值来知道下一步要做什么,那么它肯定是分支。按理说代码本身需要等待和分支来决定访问数组中的哪个元素和return.
根据相同的概念,&&
或任何其他逻辑运算符都表示分支。
这个问题很复杂,因为在一种情况下你显示的是 bool
expression
,而在另一种情况下你显示的是 int
condition
。
如果您的表达式自然计算为 int
,则使用此 int
从数组中选取一项将不会涉及任何分支。如果表达式求值的最自然类型是 bool
,那么您需要将其转换为 int
,并且此转换可能在内部涉及分支,因此您可能不会获得任何事物。我说 "probably" 因为很大程度上取决于编译器和底层 CPU 指令集,所以除非您让编译器生成反汇编并检查反汇编,否则您不会知道。
话虽如此,我要补充一点,您消除分支的追求是徒劳的。分支本身并没有什么坏处,也不会表现得很差。诚然,最好是消除分支,但前提是这样做微不足道。如果为了消除分支,您引入了一个原本不会有的数组,那么您增加的开销可能比节省的开销多一个数量级。如果引入向量而不是数组,则引入的开销可能是数组的两倍。所以,我对此的建议是:不要担心分支。