Ele*_*ent 1 c++ performance operator-keyword
我的教授表示,可以从单个“基本”运算符派生出迭代器的“所有”运算符,而不会因内联而造成速度损失。
他说:
// To implement ==, != , >, <, >=, <= only only a few cases based on attrbiutes are required
// a == b == !(a>b)&&!(a<b)
// a != b == !(a==b)
// a < b == Implemented as "actual" operator
// a > b == b < a //Argument swap!
// a >= b == a > b || a == b
// a <= b == a < b || a == b
Run Code Online (Sandbox Code Playgroud)
与以下情况相比,不会造成速度损失:
// To implement ==, != , >, <, >=, <= only only a few cases based on attrbiutes are required
// a == b == Implemented as "actual" operator
// a != b == !(a==b)
// a < b == Implemented as "actual" operator
// a > b == Implemented as "actual" operator
// a >= b == !(a < b )
// a <= b == !(a > b )
Run Code Online (Sandbox Code Playgroud)
我明白,“内联”避免了函数调用以及指令和内存中的相关开销。
但是,我有点确定 -这就是问题- 评估动态逻辑语句 a la a && b && c(例如)无法优化,首先 a,然后 b,然后 c 将被评估(一旦单个语句,评估就会停止)是假的)。
因此,!(a>b)&&!(a<b)在最坏的情况下需要调用“<-code”两次。在我的直觉中,除了代码重用之外,这是一个更糟糕的实现,因为与“直接”实现“==”运算符相比,可能会出现速度损失。
这不是对错的问题——我想明白为什么他是对的
您的问题似乎主要是关于实施a==bas !(a>b)&&!(a<b)。然而,两者代表的概念略有不同:平等和等价。在很多情况下,两者是相同的,但情况并非总是如此。
如果此特定数据类型的相等性和等价性相同,那么您是正确的!(a>b)&&!(a<b)(a>b实现为b<a)可能需要对运算符进行两次潜在的内联调用<。但是,是什么让您确信两次呼叫接线员<比一次呼叫接线员花费更多时间==?这一切都取决于数据类型,并且您当然可以创建一个operator==与operator<.
因此,假设aand的类型b是一个薄包装int(因此运算符尚未定义)。嗯,还有两件事需要考虑。首先,编译器可以生成与您编写的代码截然不同的机器代码。它可以利用许多优化,除非您查看生成的汇编代码,否则您无法准确判断一段代码的性能如何。其次,在具有流水线和其他复杂硬件系统的现代处理器中,您无法仅根据指令数量来真正预测性能。
总之,虽然您可能会说,对于简单的数据类型,“直接”实现a==b不会比实现 as 慢!(a>b)&&!(a<b),但您不能真正说它会更快。如果是的话,也很可能只是轻微的。