交换值c++; 我想知道在操作上,最有效的交换整数的方法是C++,为什么?有点像: int a =..., b = ...; a = a + b; b = a - b; a = a - b;
比使用临时工具更有效?还有其他更有效的方法吗?(不要求其他方法来交换Its),为什么它们更有效? < P>最好的方法是信任编译器并使用C++标准库函数。它们是为彼此设计的交换值c++; 我想知道在操作上,最有效的交换整数的方法是C++,为什么?有点像: int a =..., b = ...; a = a + b; b = a - b; a = a - b;,c++,performance,int,double,processing-efficiency,C++,Performance,Int,Double,Processing Efficiency,比使用临时工具更有效?还有其他更有效的方法吗?(不要求其他方法来交换Its),为什么它们更有效? < P>最好的方法是信任编译器并使用C++标准库函数。它们是为彼此设计的 std::swap将获胜 您可以对int(不需要临时变量)使用异或交换,但现在它的性能仍然不如std::swap赋值总是比算术运算快 对于std::swap是 template<typename T> void swap(T& t1, T& t2) { T temp = std::move(
std::swap
将获胜
您可以对
int
(不需要临时变量)使用异或交换,但现在它的性能仍然不如std::swap赋值总是比算术运算快
对于std::swap是
template<typename T> void swap(T& t1, T& t2) {
T temp = std::move(t1); // or T temp(std::move(t1));
t1 = std::move(t2);
t2 = std::move(temp);
}
模板无效交换(T&t1、T&t2){
T temp=std::move(t1);//或T temp(std::move(t1));
t1=std::move(t2);
t2=标准::移动(温度);
}
因此,使用临时变量比使用算术技巧要好。
使用std::swap甚至更好,因为在编程中重新发明轮子从来都不是一个好主意\include
#include <iostream>
using namespace std;
void swap(int &a, int &b){
b = (a+b) - (a=b);
}
int main() {
int a=1,b=6;
swap(a,b);
cout<<a<<b;
return 0;
}
使用名称空间std;
无效掉期(内部和a、内部和b){
b=(a+b)-(a=b);
}
int main(){
INTA=1,b=6;
掉期(a、b);
cout在我的例子中,std::swap
比下面的慢5%(都是O3优化)。一般来说,std::swap()函数调用复制构造函数可能总是比只复制部分内存慢
#include <cstring>
size_t objectSize = sizeof(Object);
char temp[objectSize];
loop {
loop {
memcpy(temp, a, objectSize);
memcpy(a, b, objectSize);
memcpy(b, temp, objectSize);
}
}
#包括
size\u t objectSize=sizeof(对象);
字符温度[objectSize];
环路{
环路{
memcpy(temp、a、objectSize);
memcpy(a、b、objectSize);
memcpy(b、temp、objectSize);
}
}
编辑:使用堆栈而不是堆内存分配。最有效的方法是不要自己尝试这样做。
这取决于你为什么要这样做。试图聪明,在C++中编写模糊代码只会减少编译器正确地优化它的机会。
假设我们使用你写的±-方式:
首先,必须从内存中加载值a和b。
然后你要做3个算术运算来“交换”它们的内容。
最后,这两个值必须再次存储在内存中。
(我不会使用实际的汇编代码,因为我对它不太熟悉,而且这个伪汇编更容易理解概念)
如果编译器完全按照您的要求执行(很可能他会忽略它并使其变得更好),那么:
2个加载,3个简单的数学函数,2个存储-7个操作
它也可以做得稍微好一些,因为加法/减法可以用内存中的1个值来完成
load 'a' into register rA
add b to rA and store in rA
subtract b from rA and store in rB
subtract rB from rA and store in rA
store rA to a
store rB to b
如果我们使用额外的tmp变量:
int a =..., b = ...;
int tmp = a;
a = b;
b = tmp;
编译器可能会认识到“tmp”只是一个临时变量,仅用于交换2个值,因此不会为其分配内存位置btu only use寄存器。
在这种情况下,它将采取以下行动:
load a into register rA
load b into register rB
store register rA to memory b
store register rB to memory a
只有4个操作-基本上是它能做的最快的,因为你需要加载2个值,你需要存储2个值,其他什么都不需要。
(对于moder nx86_64处理器,没有任何命令可以只交换内存中的2个值-其他架构可能有它,在这种情况下甚至更快)
执行这些算术运算(或xor技巧)是一个不错的练习,但在现代x86 CPU上,除了最基本的编译器之外,它不会以任何形式“更高效”。
它将使用同样多的寄存器,变量的内存量相同,但需要更多的指令来完成相同的工作。
一般来说,除非您已经检查了代码,测试和基准测试了代码,并且发现生成的程序集没有它所能达到的那么好,否则您不应该试图超越编译器
但优化几乎不需要达到这个水平,你最好把时间花在大局上。我建议在现代机器上,这可能是交换整数最慢的方法。如果你有一台有两个寄存器的机器,这可能是一个好主意,特别是如果它有一个鼓内存。好的,谢谢,我没有意识到标准函数比几行代码要快。我要补充的是,它的性能不如std::swap
,因为std::swap
可以在某些体系结构上用一条机器指令进行交换。@我的经验法则是用标准提供的函数/构造进行尝试。如果您对如果它们的性能不够好,那么就寻找替代品。还要注意,在罕见的情况下,如果手写代码的性能优于执行相同操作的标准库函数,则很可能您发现了性能缺陷。因此,在这种情况下,不要害怕与您的编译器编写者/标准库维护者联系。以及XOR swa如果您不小心尝试将一个值与其自身交换,p将失败。这是一个可能的实现,是的。但不一定会调用整数。这只是一个合理的默认值。它也可以作为t1=std::exchange(t2,t1)执行我也可以使用这个来交换<代码> UTIN 64×T/<代码>数百万次,或者它只对大的对象元素有好处?我认为,在这种情况下,值的标准交换会更快。但是你必须尝试它。但是MeMCPY可以打破C++中的对象一致性。@ Qwertiy,你能解释一下对象一致性会被打破吗?这是不可撤销的。内疚的行为。
load a into register rA
load b into register rB
store register rA to memory b
store register rB to memory a