我正在浏览一些代码,发现其中有几个三元运算符。这段代码是我们使用的一个库,应该非常快。
我在想除了节省空间之外,我们是否还能获得其他优势。
你有什么经验吗?
我正在浏览一些代码,发现其中有几个三元运算符。这段代码是我们使用的一个库,应该非常快。
我在想除了节省空间之外,我们是否还能获得其他优势。
你有什么经验吗?
三元运算符在性能上不应该与一个良好编写的等效的if
/else
语句有所不同......它们可能会解析为抽象语法树中的相同表示形式,经过相同的优化等。
如果您正在初始化常量或引用,或者在成员初始化列表中计算要使用哪个值,则不能使用if
/else
语句,但可以使用?
:
。
const int x = f() ? 10 : 2;
X::X() : n_(n > 0 ? 2 * n : 0) { }
使用 ?
:
的主要原因包括本地化和避免在同一语句/函数调用中重复冗余的部分,例如:
if (condition)
return x;
else
return y;
...仅仅是更可取的选择...
return condition ? x : y;
如果面对经验不足的程序员,或某些术语太过复杂,?
:
结构将会在噪音中丢失,因此出于可读性的考虑可以避免使用该结构。但对于更复杂的情况,比如:
fn(condition1 ? t1 : f1, condition2 ? t2 : f2, condition3 ? t3 : f3);
一个等效的 if
/else
:
if (condition1)
if (condition2)
if (condition3)
fn(t1, t2, t3);
else
fn(t1, t2, f3);
else if (condition3)
fn(t1, f2, t3);
else
fn(t1, f2, f3);
else
if (condition2)
...etc...
这会增加许多额外的函数调用,而编译器可能会或可能不会对其进行优化。
另外,?
允许你选择一个对象,然后使用其中的成员:
(f() ? a : b).fn(g() ? c : d).field_name);
等价的if
/else
语句如下:
if (f())
if (g())
x.fn(c.field_name);
else
x.fn(d.field_name);
else
if (g())
y.fn(c.field_name);
else
y.fn(d.field_name);
如果表达式 t1
, f1
, t2
等过于冗长重复,那么创建命名临时变量可能会有所帮助,但是:
要想获得与 ?
:
相匹配的性能,您可能需要使用 std::move
,除非相同的临时变量传递给调用函数中的两个 &&
参数:然后您必须避免这种方式。 那样会更加复杂和容易出错。
c ?
x :
y 会先计算 c 然后只计算 x 和 y 中的一个,这使得我们可以安全地测试指针是否为 nullptr
,同时提供一些回退值/行为。 代码仅获得实际选择的 x 和 y 中的一个的副作用。 使用命名临时变量时,您可能需要在其初始化周围使用 if
/ else
或 ?
:
以防止执行不必要的代码或执行比预期更频繁的代码。
考虑以下代码:
void is(int) { std::cout << "int\n"; }
void is(double) { std::cout << "double\n"; }
void f(bool expr)
{
is(expr ? 1 : 2.0);
if (expr)
is(1);
else
is(2.0);
}
在条件运算符版本中,数字1会进行标准转换为双精度浮点数以匹配数字2.0的类型,这意味着即使在true/1的情况下也会调用is(double)重载。但if/else语句则不会触发这个转换,true/1的分支会调用is(int)。new Image()
抛出异常,则尽管未初始化,theAudioClip
将被删除。您可以解决此问题:所有原始指针都应在第一个数据成员(即theName
)之前进行初始化,因为构造函数可能会抛出异常,如果您在构造函数周围使用try
/catch
,则如下所示:: theName((theImage = theAudioClip = nullptr, name))
。指针数据成员首先更好,但仍然脆弱。 - Tony Delroyconst
特别有用:const int foo = (a > b ? b : a - 10);
好的...
我用GCC进行了几次测试,测试这个函数调用:
add(argc, (argc > 1)?(argv[1][0] > 5)?50:10:1, (argc > 2)?(argv[2][0] > 5)?50:10:1, (argc > 3)?(argv[3][0] > 5)?50:10:1);
x = if (t) a else b