C++中的比较运算符
Comparison operators in C++
关于C++中的比较运算符,我有两个问题:
- 循环时,两种方式中哪一种更有效(
mdata
和mfirst_free
的类型也是double*
):
for (double *p = mdata; p < mfirst_free; ++p) { .. }
for (double *p = mdata; p != mfirst_free; ++p) { .. }
我猜在前面,相同的答案对所有基元类型都有效——int
、double
和指针。对吧
我知道<
版本更安全,因为如果我以比预期更大的指针开始,它就不会是无限循环。但是,当我确信我不会得到无效的输入时,哪个版本更有效?
- 在我自己的类中重写比较运算符时,是否有一些组合是最有效的,是否有最小的所需(或推荐)组合来推导其余的
让我们假设尝试保存每个处理器周期的情况——最好的选择是什么?有没有其他更优雅的?
一如既往,亲自查看并查看生成的代码。在Ubuntu 14.04上使用g++4.8,您可以获得
movq -16(%rbp), %rax
movq %rax, -32(%rbp)
jmp .L2
.L3:
addq $8, -32(%rbp)
.L2:
movq -32(%rbp), %rax
cmpq -8(%rbp), %rax
jb .L3
movq -16(%rbp), %rax
movq %rax, -24(%rbp)
jmp .L4
.L5:
addq $8, -24(%rbp)
.L4:
movq -24(%rbp), %rax
cmpq -8(%rbp), %rax
jne .L5
正如您所看到的,唯一相关的区别是jb .L3
与jne .L5
。
因此,从性能的角度来看,我认为两者是等效的。
在回答第二个问题时,比较所需的最小值是operator<
。你可以从中推断出其他一切,例如
bool operator==(const T &x, const T &y) {
return !(x < y) && !(y < x);
}
bool operator!=(const T &x, const T &y) {
return !(x == y);
}
bool operator>(const T &x, const T &y) {
return y < x;
}
bool operator<=(const T &x, const T &y) {
return !(y < x);
}
bool operator>=(const T &x, const T &y) {
return !(x < y);
}
当然,只有当你有通常的比较语义时,这才是真的。
首先,在纯c++术语中,没有正确的答案来回答您的问题,因为标准没有指定它,它由编译器和CPU自行决定。
实际上,你在问"如果不相等则分支"指令是否比"如果较少则分支"的指令花费更少的时间。在我遇到的所有CPU中,答案都是"否"——前提是你不会因为错误的分支预测而措手不及。
据我所知,这真的没有什么区别。我相信
p != mfirst_free
会被翻译成类似的程序集
loop
CMP p mfirst_free
BEQ exit
{...body...}
B loop
exit
而
p < mfirst_free
将转换为相同的,但它将不是BEQ指令,而是BGE。执行相同数量的指令需要相同的时间。
-有多种方法可以将for循环转换为程序集,但我的观点是,据我所知,您使用的每个比较运算符都会导致相同的运行时间。-
如果计数器变量是整数或指针,则效率可能没有差异。只要变量只是增加(一),并且开始时小于或等于结束值,效果是一样的。
但是C++迭代器不一定实现operator<
。事实上,只有RandomAccessIterator
需要这样做(请参阅http://en.cppreference.com/w/cpp/iterator)。因此C++11将for(auto&& v : values)
转换为for(auto it = std::begin(values); it != std::end(values); ++it)
。例如,std::forward_list
只有ForwardIterators
,因此operator<
不能用于对其进行迭代
如果使用OpenMP进行并行化,则需要operator<
:
#pragma omp parallel for
for(auto it = std::begin(values); it < std::end(values); ++it)
因为它需要将循环拆分为更小的循环。
我想,通常情况下,最好使用operator!=
与所有迭代器类型兼容,除非你做了迭代之外的其他事情(增加一个以上,等等),使用浮点值作为计数器,或者使用OpenMP。
- 为什么比较运算符如此快速
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 关于 std::min, std::max 中的比较运算符的混淆
- 三向比较运算符成员与非成员实现
- 标准::可选枚举的比较运算符
- 为什么字符串比较的 == 运算符相对于任一字符串长度线性时间(似乎)?
- C++分数混合比较运算符错误
- <<运算符优先级与字符串比较
- 不能将重载比较运算符与 Catch 测试一起使用
- 重构使用动态强制转换的 std::set 的比较运算符
- ">"运算符和"<"运算符如何进行字符串比较?
- "operator()"在重载运算符方法中是什么意思,在priority_queue(STL)中用作C++中的比较器?
- C++使用关系运算符比较字符串
- 为什么使用 and 运算符比较 if 语句中的 2 个对象会抛出错误,而使用 2 if 语句则不会
- 使用关系运算符比较指针意味着什么
- 运算符<比较多个字段
- 运算符==比较两个不同的类
- 使用==运算符比较字符串到0
- 使用'if'语句和"<<"时的结果错误,'>>'运算符比较 3 个整数