提高C++性能的编程技术笔记:临时对象+测试代码
生活随笔
收集整理的這篇文章主要介紹了
提高C++性能的编程技术笔记:临时对象+测试代码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
類型不匹配:一般情況是指當需要X類型的對象時提供的卻是其它類型的對象。編譯器需要以某種方式將提供的類型轉換成要求的X類型。這一過程可能會產生臨時對象。
按值傳遞:創建和銷毀臨時對象的代價是比較高的。倘若可以,我們應該按指針或者引用來傳遞對象以避免生成臨時對象。
按值返回:如果編寫的函數是按值返回對象(與引用或者指針相對),就很可能生成臨時對象。
可以使用operator=()消除臨時對象。
臨時對象會以構造函數和析構函數的形式降低一半的性能。
將構造函數聲明為explicit,可以阻止編譯器在幕后使用類型轉換。
編譯器常常創建臨時對象來解決類型不匹配問題。通過函數重載可以避免這種情況。
如果可能,應盡量避免使用對象拷貝。按引用傳遞和返回對象。
在<op>可能是”+、-、*”或者”/”的地方,使用<op>=運算符可以消除臨時對象。
以下是測試代碼(temporary_object.cpp):
#include "temporary_object.hpp"
#include <iostream>
#include <chrono>
#include <string>namespace temporary_object_ {// reference: 《提高C++性能的編程技術》:第五章:臨時對象class Rational {friend Rational operator + (const Rational&, const Rational&);public:Rational(int a = 0, int b = 1) : m(a), n(b) {}
private:int m; // 分子int n; // 分母
};template<class T>
void g(T formalArg)
{}std::string f()
{std::string s;// ....return s;
}int test_temporary_object_1()
{
{ // 對象定義// 實例化Rational對象: 只有第一種初始化形式可以保證在編譯器的執行過程中不產生臨時對象。如果使用第2種或第3種形式,很可能產生臨時對象,這依賴于編譯器的實現。// 實際上,大多數編譯器會通過優化省去臨時對象,所以此處給出的3種初始化形式在效率上是等效的Rational r1(100); // 1Rational r2 = Rational(100); // 2Rational r3 = 100; // 3
}{ // 類型不匹配// Rational類沒有聲明接收整形參數的賦值運算符。然而編譯器希望右邊是Rational對象,這樣可以按字節傳給左邊。所以,編譯器必須想辦法將我們提供的整形參數轉換成Rational對象。幸運的是(對性能來說是不幸的),我們有構造函數知道如何根據一個整形參數創建Rational對象// 為了易于編程,編譯器可以自由地轉換類型。新的C++標準允許我們限制編譯器禁止這種轉換,可以通過聲明構造函數為explicit來實現Rational r;r = 100;// 可以通過重載函數Rational::operator=()以接收整形參數,從而消除臨時對象// Rational& operator = (int a) { m=a; n=1; return *this; }// 同樣的原理可以推廣到所有的函數調用。假設g()是一個接收string引用參數的函數調用// void g(const string& s) { ... }// 除非重載g()讓它接收char*參數,否則調用g("message")會產生臨時的string對象
}{ // 按值傳遞// 因為存在局部參數formalArg, g()的激活記錄在棧上設置了占位符。編譯器復制對象t的內容至g()位于棧上的formalArg中。對此,一種常用的做法是生成臨時對象// 編譯器將創建int類型的臨時對象,并且使用t作為輸入參數來復制構造它.然后臨時對象作為實參傳遞給g()。該新創建的臨時對象將按引用方式傳遞給g(). int t;g(t);
}{ // 按值返回// f()的返回值是string對象,編譯器生成臨時對象來存儲返回值。然后存儲f()返回值的臨時對象賦給左邊的對象pstd::string p;p = f();std::string s1 = "Hello";std::string s2 = "Wold";std::string s3_1 = s1 + s2; // 此處沒有臨時對象std::string s3_2;s3_2 = s1 + s2; // 此處產生臨時對象
}{ // 使用op=()消除臨時對象std::string s1, s2, s3;s1 = s2 + s3; // 此處產生臨時對象s3 = s1; // operator=(),沒有臨時對象s3 += s2; // operator+=(),沒有臨時對象}
}{ // 兩種方式計算s5std::string s1, s2, s3, s4, s5;// 1. 產生三個臨時對象s5 = s1 + s2 + s3 + s4;// 2. 雖然"丑陋"但更高效,因為它不產生臨時對象s5 = s1;s5 += s2;s5 += s3;s5 += s4;
}return 0;
}} // namespace temporary_object_
GitHub:https://github.com/fengbingchun/Messy_Test
總結
以上是生活随笔為你收集整理的提高C++性能的编程技术笔记:临时对象+测试代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 提高C++性能的编程技术笔记:虚函数、返
- 下一篇: 提高C++性能的编程技术笔记:单线程内存