C++ Primer 5th中练习13.53
Exercise 13.53: As a matter of low-level efficiency, the HasPtr assignment operator is not ideal. Explain why. Implement a copy-assignment and move assignment operator for HasPtr and compare the operations executed in your new move-assignment operator versus the copy-and-swap version.
.h文件:
.cpp文件
测试代码
实现copy assignment
和move assignment
:
.h文件:
.cpp文件
测试代码:
所以总结一下:
copy-and-swap和copy assignment差不多
- copy-and-swap和copy assignment差不多,其实copy-and-swap多跑几次的结果是:
[Chap1] : ) ./main
执行时间: 0.140264
[Chap1] : ) ./main
执行时间: 0.141963
[Chap1] : ) ./main
执行时间: 0.130669
[Chap1] : ) ./main
执行时间: 0.142128
[Chap1] : ) ./main
执行时间: 0.133721
[Chap1] : ) ./main
执行时间: 0.13198
[Chap1] : ) ./main
执行时间: 0.136442
[Chap1] : ) ./main
执行时间: 0.13367
- 而copy assignment多跑几次的结果是:
[Chap1] : ) ./main
执行时间: 0.130349
[Chap1] : ) ./main
执行时间: 0.120378
[Chap1] : ) ./main
执行时间: 0.122632
[Chap1] : ) ./main
执行时间: 0.121985
[Chap1] : ) ./main
执行时间: 0.124312
[Chap1] : ) ./main
执行时间: 0.122294
[Chap1] : ) ./main
执行时间: 0.123275
[Chap1] : ) ./main
执行时间: 0.123618
[Chap1] : ) ./main
执行时间: 0.123131
- 所以copy-assignment比copy-and-swap是客观上的快(如果算法精度有这差距不得水篇文章?)
根本原因目前我不知,但是我们可以插入一些输出语句来分析一下。首先copy-and-swap它需要调用
copy constructor来用hp1初始化rhs,然后才执行copy-and-swap的函数体。而copy- assignment直接 执行其函数体。客观上两者都进行了一次copy,前者发生在copy constructor的初始化列表里(ps(new std::string(*hp.ps))
),后者发生在copy- assignment的函数体内(std::string *newData = new std::string(*rhs.ps);
),然后前者还要在copy-and-swap函数体内执行swap操作(swap(*this,rhs);
),但是后者只进行了赋值操作(ps = newData; i = rhs.i;
)。难道是因为swap比赋值开销大一些?不过总体性能是差不多的。
copy-and-swap比move assignment肉眼可见的慢
- copy-and-swap比move assignment肉眼可见的慢,如果前者多跑几次的话:
[Chap1] : ) ./main
执行时间: 0.0214209
[Chap1] : ) ./main
执行时间: 0.0156422
[Chap1] : ) ./main
执行时间: 0.0196867
[Chap1] : ) ./main
执行时间: 0.0143008
[Chap1] : ) ./main
执行时间: 0.0143276
[Chap1] : ) ./main
执行时间: 0.0190589
[Chap1] : ) ./main
执行时间: 0.014424
[Chap1] : ) ./main
执行时间: 0.0197936
[Chap1] : ) ./main
执行时间: 0.0188477
- ,而move assignment多跑几次的话:
[Chap1] : ) ./main
执行时间: 0.00741979
[Chap1] : ) ./main
执行时间: 0.00479204
[Chap1] : ) ./main
执行时间: 0.00680325
[Chap1] : ) ./main
执行时间: 0.00676896
[Chap1] : ) ./main
执行时间: 0.00675975
[Chap1] : ) ./main
执行时间: 0.00691304
[Chap1] : ) ./main
执行时间: 0.00686121
[Chap1] : ) ./main
执行时间: 0.00430117
- 所以这里的差距是哪里造成的呢?首先copy-and-swap需要调用move constructor,然后才会执行其函数体内的
swap(*this,rhs);
。有趣的是, move assignment做的就是move constructor的事情,所以前者硬生生比后者多执行了一个swap(*this,rhs);
~~。
以上都是根据结果进行的猜测,真实原因不知。
参考