日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

提高C++性能的编程技术笔记:虚函数、返回值优化+测试代码

發布時間:2023/11/27 生活经验 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 提高C++性能的编程技术笔记:虚函数、返回值优化+测试代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

虛函數:在以下幾個方面,虛函數可能會造成性能損失:構造函數必須初始化vptr(虛函數表);虛函數是通過指針間接調用的,所以必須先得到指向虛函數表的指針,然后再獲得正確的函數偏移量;內聯是在編譯時決定的,編譯器不可能把運行時才解析的虛函數設置為內聯

無法內聯虛函數造成的性能損失最大。

某些情況下,在編譯期間解析虛函數的調用是可能的,但這是例外情況。由于在編譯期間不能確定所調用的函數所屬的對象類型,所以大多數虛函數調用都是在運行期間解析的。編譯期間無法解析對內聯造成了負面影響。由于內聯是在編譯期間確定的,所以它需要具體函數的信息,但如果在編譯期間不能確定將調用哪個函數,就無法使用內聯。

評估虛函數的性能損失就是評估無法內聯該函數所造成的損失。這種損失的代價并不固定,它取決于函數的復雜程度和調用頻率。一種極端情況是頻繁調用的簡單函數,它們是內聯的最大受益者,若無法內聯則會造成重大性能損失。另一極端情況是很少調用的復雜函數。

通過對類選擇進行硬編碼或者將它作為模板參數來傳遞,可以避免使用動態綁定。

因為函數調用的動態綁定是繼承的結果,所以消除動態綁定的一種方法是用基于模板的設計來替代繼承。模板把解析的步驟從運行期間提前到編譯期間,從這個意義上說,模板提高了性能。而對于我們所關心的編譯時間,適當增加也是可以接受的。

返回值優化通過轉換源代碼和消除對象的創建來加快源代碼的執行速度,這種優化稱為返回值優化(Return Value Optimization, RVO)。

編譯器優化要保證原來計算的正確性。然而對于RVO來說,這一點并不總是易于實現的。既然RVO不是強制執行的,編譯器就不會對復雜的函數執行RVO。例如,如果函數有多個return語句返回不同名稱的對象,這樣就不會執行RVO。如果想使用RVO,就必須返回相同名稱的對象。

當編譯器無法執行RVO時,可按計算性構造函數的形式來實現。

如果必須按值返回對象,通過RVO可以省去創建和銷毀局部對象的步驟,從而改善性能。

RVO的應用要遵照編譯器的實現而定。這需要參考編譯器文檔或通過實驗來判斷是否使用RVO以及何時使用。

通過編寫計算性構造函數可以更好地使用RVO。

以下是測試代碼(return_value_optimization.cpp):

#include "return_value_optimization.hpp"
#include <iostream>
#include <chrono>namespace return_value_optimization_ {// reference: 《提高C++性能的編程技術》:第四章:返回值優化class Complex {friend Complex operator + (const Complex&, const Complex&);friend void Complex_Add(const Complex&, const Complex&, Complex&);friend Complex Complex_Add2(const Complex&, const Complex&);friend Complex Complex_Add3(const Complex&, const Complex&);public:Complex(double r =0.0, double i =0.0) : real(r), imag(i) {} // 默認構造函數Complex(const Complex& c) : real(c.real), imag(c.imag) {} // 拷貝構造函數Complex(const Complex& a, const Complex& b) : real(a.real + b.real), imag(a.imag + b.imag) {} // 計算性構造函數Complex& operator = (const Complex& c) { this->real = c.real; this->imag = c.imag; return *this; }// 賦值運算符~Complex() {}private:double real;double imag;};Complex operator + (const Complex& a, const Complex& b)
{Complex retVal;retVal.real = a.real + b.real;retVal.imag = a.imag + b.imag;return retVal;
}// 消除局部對象retVal,直接把返回值放到__tempResult臨時對象中來實現優化,這就是返回值優化(RVO)
void Complex_Add(const Complex& a, const Complex&b, Complex& __tempResult)
{__tempResult.real = a.real + b.real;__tempResult.imag = a.imag + b.imag;
}Complex Complex_Add2(const Complex& a, const Complex& b)
{Complex retVal;retVal.real = a.real + b.real;retVal.imag = a.imag + b.imag;return retVal;
}// 通過計算性構造函數來執行加操作
Complex Complex_Add3(const Complex& a, const Complex& b)
{return Complex(a, b);
}int test_return_value_optimization_1()
{// 測試兩種加操作的實現性能:普通加操作、RVO加操作using namespace std::chrono;high_resolution_clock::time_point time_start, time_end;const int cycle_number {100000000};{ // 普通加操作Complex a(1, 0);Complex b(2, 0);Complex c;time_start = high_resolution_clock::now();for (int i = 0; i < cycle_number; ++i) {c = a + b;}time_end = high_resolution_clock::now();std::cout<<"common add time spent: "<<(duration_cast<duration<double>>(time_end - time_start)).count()<<" seconds\n";
}{ // RVO加操作Complex a(1, 0);Complex b(2, 0);Complex c;time_start = high_resolution_clock::now();for (int i = 0; i < cycle_number; ++i) {Complex_Add(a, b, c);}time_end = high_resolution_clock::now();std::cout<<"RVO add time spent: "<<(duration_cast<duration<double>>(time_end - time_start)).count()<<" seconds\n";
}// 測試兩種加操作的實現性能:普通加操作、使用計算性構造函數{ // 普通加操作Complex a(1, 0);Complex b(2, 0);Complex c;time_start = high_resolution_clock::now();for (int i = 0; i < cycle_number; ++i) {c = Complex_Add2(a, b);}time_end = high_resolution_clock::now();std::cout<<"common add time spent: "<<(duration_cast<duration<double>>(time_end - time_start)).count()<<" seconds\n";
}{ // 使用計算性構造函數Complex a(1, 0);Complex b(2, 0);Complex c;time_start = high_resolution_clock::now();for (int i = 0; i < cycle_number; ++i) {c = Complex_Add3(a, b);}time_end = high_resolution_clock::now();std::cout<<"計算性構造函數 add time spent: "<<(duration_cast<duration<double>>(time_end - time_start)).count()<<" seconds\n";}return 0;
}} // namespace return_value_optimization_

運行結果如下:

GitHub:?https://github.com/fengbingchun/Messy_Test ?

總結

以上是生活随笔為你收集整理的提高C++性能的编程技术笔记:虚函数、返回值优化+测试代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。