Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
交换值c++; 我想知道在操作上,最有效的交换整数的方法是C++,为什么?有点像: int a =..., b = ...; a = a + b; b = a - b; a = a - b;_C++_Performance_Int_Double_Processing Efficiency - Fatal编程技术网

交换值c++; 我想知道在操作上,最有效的交换整数的方法是C++,为什么?有点像: int a =..., b = ...; a = a + b; b = a - b; a = a - b;

交换值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(

比使用临时工具更有效?还有其他更有效的方法吗?(不要求其他方法来交换Its),为什么它们更有效?

< P>最好的方法是信任编译器并使用C++标准库函数。它们是为彼此设计的

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