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

歡迎訪問 生活随笔!

生活随笔

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

生活经验

提高C++性能的编程技术笔记:构造函数和析构函数+测试代码

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

對象的創建和銷毀往往會造成性能的損失。在繼承層次中,對象的創建將引起其先輩的創建。對象的銷毀也是如此。其次,對象相關的開銷與對象本身的派生鏈的長度和復雜性相關。所創建的對象(以及其后銷毀的對象)的數量與派生的復雜度成正比。

并不是說繼承根本上就是代碼性能的絆腳石。我們必須區分全部計算開銷、必須開銷和計算損失(computional penalty). 全部計算開銷是一次計算中所執行的全部指令的總和。必須開銷是全部指令的子集,它的結果是必要的。這部分計算是必需的,其余部分即為計算損失。計算損失是可以通過別的設計和實現來消除的那部分計算。

???????? 我們不能斷言采用了復雜的繼承的設計一定是壞的,也不能斷定它們總是帶來性能損失。我們只能說總的開銷會隨著派生樹規模的增長而增加。如果所有的計算都是有價值的,那么它們都是必須的開銷。實際上,繼承層次不見得是完善的,在這種情況下,它們很可能會導致計算損失。

???????? 對象的復合與繼承一樣,都引入了與對象創建和銷毀有關的類似性能問題。在對象被創建(或銷毀)時,必須同時創建(或銷毀)它所包含的成員對象。

???????? 創建和銷毀被包含對象是另一個值得注意的問題:在創建(或銷毀)被包含對象時無法阻止子對象的創建(或銷毀),因為這是編譯器自動強加的步驟。

???????? 性能優化經常需要犧牲一些其它軟件目標,諸如靈活性、可維護性、成本和重用之類的重要目標經常必須為性能讓步。

???????? 在C++中,不自覺地在程序開始處預先定義所有對象的做法是一種浪費。因為這樣可能會創建一些直到最后都沒有用到的對象。在C++中,把變量的創建延遲到第一次使用前。

???????? 構造函數和析構函數可以像手工編寫的C代碼一樣有效。然而在實踐中,它們經常包含冗余計算。

???????? 對象的創建(或銷毀)觸發對父對象和成員對象的遞歸創建(或銷毀)。

???????? 要確保所編寫的代碼實際使用了所有創建的對象和這些對象所執行的計算。

???????? 對象的生命周期不是無償的。至少對象的創建和銷毀會消耗CPU周期。不要隨意創建一個對象,除非你打算使用它。通常情況下,要等到需要使用對象的地方再創建它。

???????? 編譯器必須初始化被包含的成員對象之后再執行構造函數體。你必須在初始化階段完成成員對象的創建。這可以降低隨后在構造函數部分調用賦值操作符的開銷。在某些情況下,這樣也可以避免臨時對象的產生。

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

#include "constructors_and_destructors.hpp"
#include <iostream>
#include <string>
#include <mutex>
#include <chrono>namespace constructors_destructors_ {// reference: 《提高C++性能的編程技術》:第二章:構造函數和析構函數class SimpleMutex { // 單獨的鎖類
public:SimpleMutex(std::mutex& mtx) : mymtx(mtx) { acquire(); }~SimpleMutex() { release(); }private:void acquire() { mymtx.lock(); }void release() { mymtx.unlock(); }std::mutex& mymtx; 
};class BaseMutex { // 基類
public:BaseMutex(std::mutex& mtx) {}virtual ~BaseMutex() {}
};class DerivedMutex : public BaseMutex {
public:DerivedMutex(std::mutex& mtx) : BaseMutex(mtx), mymtx(mtx) { acquire(); }~DerivedMutex() { release(); }private:void acquire() { mymtx.lock(); }void release() { mymtx.unlock(); }std::mutex& mymtx;};class Person1 {
public:Person1(const char* s) { name = s; } // 隱式初始化和顯示賦值private:std::string name; 
};class Person2 {
public:Person2(const char* s) : name(s) {} // 顯示初始化private:std::string name;
};int test_constructors_destructors_1()
{// 測試三種互斥鎖的實現// Note:與書中實驗結果有差異,在這里繼承對象并不會占用較多的執行時間,在這里這三種所占用時間基本差不多using namespace std::chrono;high_resolution_clock::time_point time_start, time_end;const int cycle_number {100000000};int  shared_counter {0};{ // 1.直接調用mutexstd::mutex mtx;shared_counter = 0;time_start = high_resolution_clock::now();for (int i = 0; i < cycle_number; ++i) {mtx.lock();++shared_counter;mtx.unlock();}time_end = high_resolution_clock::now();std::cout<< "time spen1: "<<(duration_cast<duration<double>>(time_end - time_start)).count()<< " seconds\n";
}{ // 2.不從基類繼承的獨立互斥對象std::mutex mtx;shared_counter = 0;time_start = high_resolution_clock::now();for (int i = 0; i < cycle_number; ++i) {SimpleMutex m(mtx);++shared_counter;}time_end = high_resolution_clock::now();std::cout<< "time spen2: "<<(duration_cast<duration<double>>(time_end - time_start)).count()<<" seconds\n";
}{ // 3.從基類派生的互斥對象std::mutex mtx;shared_counter = 0;time_start = high_resolution_clock::now();for (int i = 0; i < cycle_number; ++i) {DerivedMutex m(mtx);++shared_counter;}time_end = high_resolution_clock::now();std::cout<< "time spen3: "<<(duration_cast<duration<double>>(time_end - time_start)).count()<<" seconds\n";}// 隱式初始化和顯示賦值與顯示初始化性能對比:使用顯示初始化操作要優于使用隱式初始化和顯示賦值操作
{ // 1.隱式初始化和顯示賦值操作time_start = high_resolution_clock::now();for (int i = 0; i < cycle_number; ++i) {Person1 p("Pele");	}time_end = high_resolution_clock::now();std::cout<< "隱式初始化, time spen: "<<(duration_cast<duration<double>>(time_end - time_start)).count()<<" seconds\n";
}{ // 2.顯示初始化操作time_start = high_resolution_clock::now();for (int i = 0; i < cycle_number; ++i) {Person2 p("Pele");}time_end = high_resolution_clock::now();std::cout<<"顯示初始化, time spen: "<<(duration_cast<duration<double>>(time_end - time_start)).count()<<" seconds\n";
}return 0;
}} // namespace constructors_destructors_

運行結果如下:

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

總結

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

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