色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何使用in_place_t和相關標簽高效創建

C語言與CPP編程 ? 來源:DeepNoMind ? 作者:DeepNoMind ? 2022-10-13 08:59 ? 次閱讀

本系列是開源書C++ Best Practises[1]的中文版,全書從工具、代碼風格、安全性、可維護性、可移植性、多線程、性能、正確性等角度全面介紹了現代C++項目的最佳實踐。本文是該系列的第六篇。

C++最佳實踐:

1. 工具

2. 代碼風格

3.安全性

4.可維護性

5.可移植性及多線程

6.性能(本文)

7.正確性和腳本

性能

盡量使用前置聲明

使用這種聲明方式:

//someheaderfile
classMyClass;

voiddoSomething(constMyClass&);

而不是這樣:

//someheaderfile
#include"MyClass.hpp"

voiddoSomething(constMyClass&);

同樣也使用于模板:

templateclassMyTemplatedType;

這種方式可以主動減少編譯時間并重新構建依賴關系。

注意: 前置聲明會阻礙內聯和優化,建議在發布版本中使用鏈接時優化或鏈接時代碼生成。

避免不必要的模板實例化

模板不要隨便實例化,實例化過多模板,或者模板代碼多于必要的數量,會增加編譯代碼的大小和構建時間。

更多示例請參考: Template Code Bloat Revisited: A Smaller make_shared[2]

避免遞歸模板實例化

遞歸模板實例化可能會給編譯器帶來很大的負擔,并且代碼更加難以理解。

如果可能的話,考慮使用可變參數展開和折疊[3]。

分析構建

可以使用Templight[4]工具分析項目的構建時間,它需要花一些時間來構建,但一旦這樣做了,可以用來替換clang++。

使用Templight進行構建之后,需要對結果進行分析,templight-tools[5]項目提供了各種方法(建議使用callgrind轉換并使用kcachegrind對結果進行可視化)。

隔離頻繁更改的頭文件

不要包含不需要的頭文件

編譯器必須處理看到的每個include指令,即使只是在看到#ifndefinclude保護符后立即停止,仍然必須打開文件并進行處理。

include-what-you-use[6]是一個可以幫我們確定需要哪些頭文件的工具。

減少預處理器的工作

這是“隔離頻繁更改的頭文件”和“不要包含不需要的頭文件”的一般形式。類似BOOST_PP這樣的工具可能非常有用,但也給預處理器帶來了巨大的負擔。

考慮使用預編譯頭文件

使用預編譯頭文件可以大大減少大型項目的編譯時間,選定的頭文件被編譯成中間形式(PCH文件),編譯器可以更快處理。建議只將經常使用但很少更改的頭文件定義為預編譯頭文件(例如系統頭文件和庫頭文件),以減少編譯時間。但必須記住,使用預編譯頭文件有幾個缺點:

預編譯頭文件不可移植。

生成的PCH文件依賴于機器。

生成的PCH文件可能相當大。

它會破壞頭文件依賴關系。由于有預編譯頭文件,每個文件都有可能包含標記為預編譯頭文件的每個頭文件。因此,如果禁用預編譯頭文件,可能會導致構建失敗。如果需要發布庫之類的項目,這可能是個問題。正因為如此,強烈建議在第一次構建時啟用預編譯頭,而在后續構建時將其關閉。

大多數常見的編譯器都支持預編譯頭文件,比如GCC[7]、Clang[8]和Visual Studio[9]。像cotire[10](cmake的插件)這樣的工具可以幫助我們在構建系統中添加預編譯的頭文件。

考慮使用工具

工具并不意味著可以取代好的設計。

ccache[11],用于類unix操作系統的編譯結果緩存

clcache[12],cl.exe的編譯結果緩存(MSVC)

warp[13],Facebook的預處理器

將tmp放在Ramdisk上

詳見YouTube視頻: https://www.youtube.com/watch?v=t4M3yG1dWho

使用gold鏈接器

如果是在Linux上,考慮使用GCC的gold鏈接器(ld.gold)。

參考: gold: Google Releases New and Improved GCC Linker[14]

運行時

分析代碼

在不分析代碼的情況下,無法真正找到瓶頸在哪里。

http://developer.amd.com/tools-and-sdks/opencl-zone/codexl/

http://www.codersnotes.com/sleepy

簡化代碼

代碼越清晰、越簡單、越容易閱讀,編譯器就越有可能更好的將其實現。

使用初始化列表

//This
std::vectormos{mo1,mo2};

//-or-
automos=std::vector{mo1,mo2};
//Don'tdothis
std::vectormos;
mos.push_back(mo1);
mos.push_back(mo2);

通過減少對象復制并調整容器大小,初始化列表能顯著提升性能。

減少臨時對象

//Insteadof
automo1=getSomeModelObject();
automo2=getAnotherModelObject();

doSomething(mo1,mo2);
//consider:
doSomething(getSomeModelObject(),getAnotherModelObject());

這類代碼將阻礙編譯器執行move操作……

啟用移動(move)操作

move操作是C++11中最受歡迎的特性之一,該操作允許編譯器通過移動臨時對象從而避免額外的拷貝。

某些代碼(例如聲明自己的析構函數或賦值操作符或拷貝構造函數)會阻止編譯器生成移動構造函數。

對于大多數代碼,下面這么一個簡單的定義:

ModelObject(ModelObject&&)=default;

...就足夠了,不過MSVC2013似乎不支持這段代碼。

避免shared_ptr拷貝

shared_ptr對象的拷貝成本比想象的要高得多,因為引用計數必須是原子的和線程安全的。這條規則只是再次強調了上面的注意事項: 避免臨時對象和過多的對象副本。僅僅因為我們使用了pImpl,并不意味著副本沒有代價。

盡可能減少拷貝和重分配

對于更簡單的情況,可以使用三元操作符:

//BadIdea
std::stringsomevalue;

if(caseA){
somevalue="ValueA";
}else{
somevalue="ValueB";
}
//BetterIdea
conststd::stringsomevalue=caseA?"ValueA":"ValueB";

使用立即調用的lambda[15]可以簡化更復雜的情況。

//BadIdea
std::stringsomevalue;

if(caseA){
somevalue="ValueA";
}elseif(caseB){
somevalue="ValueB";
}else{
somevalue="ValueC";
}
//BetterIdea
conststd::stringsomevalue=[&]("&"){
if(caseA){
return"ValueA";
}elseif(caseB){
return"ValueB";
}else{
return"ValueC";
}
}();

避免多余的異常

在正常處理期間,內部拋出和捕獲的異常會降低應用程序的執行速度。由于調試器會監視和報告每個異常事件,因此還會破壞調試器的用戶體驗。最好盡可能避免內部異常處理。

拋棄new

我們已經知道不該使用裸內存訪問,因此改用unique_ptr和shared_ptr,對吧?堆分配比棧分配昂貴得多,但有時不得不用。更糟的是,創建shared_ptr實際上需要在堆上分配2次。

然而,make_shared函數可以將其減少為一次。

std::shared_ptr(newModelObject_Impl());

//shouldbecome
std::make_shared();//(it'salsomorereadableandconcise)

優先選擇unique_ptr而不是shared_ptr

可能的話,使用unique_ptr而不是shared_ptr。unique_ptr是不可復制的,因此不需要跟蹤副本,比shared_ptr性能更好。另外,類似于shared_ptr和make_shared的關系,應該使用make_unique(C++14或更高版本)來創建unique_ptr:

std::make_unique();

目前的最佳實踐也建議從工廠函數返回unique_ptr,然后在必要時將unique_ptr轉換為shared_ptr。

std::unique_ptrfactory();

autoshared=std::shared_ptr(factory());

拋棄std::endl

std::endl表示刷新操作,等價于" " << std::flush。

限制變量作用域

變量應該盡可能晚聲明,最好只在可以初始化對象時聲明。減小變量作用域可以減少內存的使用,提高代碼效率,并幫助編譯器進一步優化代碼。

//GoodIdea
for(inti=0;i

對于C++17及以后版本,考慮在if和switch語句中初始化變量:

if(MyObjectobj(index);obj.good()){
//dosomethingifobjisgood
}else{
//dosomethingifobjisnotgood
}

Github上對此有專門的討論: https://github.com/lefticus/cppbestpractices/issues/52

優先選擇double類型而不是float類型,但需要先測試

根據情況和編譯器的優化能力,一種可能比另一種更快。選擇float意味著精度較低,并可能由于類型轉換而影響性能。在可向量化操作中,如果能夠犧牲精度,float可能更快。

double是C++中浮點值的默認類型,因此推薦作為默認選項。

參考下面的文章獲取更多信息: double or float, which is faster?[16]

優先選擇++i而不是i++

...當語義正確時,前置自增比后置自增更快[17],因為前置自增不需要創建對象副本。

//BadIdea
for(inti=0;i

即使許多現代編譯器將這兩個循環優化為相同的匯編代碼,選擇++i仍然是一種良好的實踐。你永遠無法確定代碼會不會使用不帶優化的編譯器,因此沒有任何理由不這樣做。此外,編譯器有可能只對整數類型進行優化,而不一定對所有迭代器或其他用戶自定義類型進行優化。

總而言之,如果前置自增操作符與后置自增操作符在語義上相同,那么使用前置自增操作符總是更好。

char是char, string是string

//BadIdea
std::cout<

看上去區別不大,但是" "必須被編譯器解析為const char *,必須在寫入流(或附加到字符串)時對?進行范圍檢查,而' '是已知的單個字符,可以節約許多CPU指令。

如果多次調用效率低下的代碼,可能會對性能產生影響,更重要的是,考慮這兩種使用情況會讓我們更多的考慮編譯器和運行時在執行代碼時必須做什么。

永遠不要用std::bind

std::bind的開銷(包括編譯時和運行時)幾乎總是比需要的更多,相反,我們只需使用lambda。

//BadIdea
autof=std::bind(&my_function,"hello",std::_1);
f("world");

//GoodIdea
autof=[](conststd::string&s){returnmy_function("hello",s);};
f("world");

了解標準庫

正確使用供應商提供的標準庫中已經高度優化的組件。

in_place_t及相關內容

知道如何使用in_place_t和相關標簽高效創建諸如std::tuple、std::any和std::variant等對象。

審核編輯:彭靜
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C++
    C++
    +關注

    關注

    22

    文章

    2108

    瀏覽量

    73623
  • 代碼
    +關注

    關注

    30

    文章

    4780

    瀏覽量

    68529
  • 編譯器
    +關注

    關注

    1

    文章

    1624

    瀏覽量

    49108

原文標題:C++最佳實踐 | 6. 性能

文章出處:【微信號:C語言與CPP編程,微信公眾號:C語言與CPP編程】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    求時間t如何創建

    小白求助:已知一公式里有時間參數t。求時間t如何創建
    發表于 09-23 21:26

    Error: Can't place multiple pins assigned to pin location Pin_C1問題的解決

    在進行nios實驗中使用epcs flash ip核時,在quartus II 進行布局布線時出現以下錯誤:Error: Can't place multiple pins assigned
    發表于 07-21 19:34

    BLE-Beacon Android應用程序是用來創建標簽的嗎?

    您好!我正在嘗試重新創建一個類似的應用程序。有人知道Android組件是用來創建標簽的嗎?當做戴維 以上來自于百度翻譯 以下為原文Hi I am trying to recreate a
    發表于 12-04 11:44

    LabVIEW中創建XML文件,如何在標簽名字中加入空格?

    我需要的標簽名稱是這種格式,但是創建元素時,標簽名稱不能有空格、=和引號,否則報錯.后來我嘗試用了"通過命名空間創建元素"控件,但生成的標簽
    發表于 03-18 00:13

    如何將值寫入所有相同標簽名稱的控件

    各位大師,我這里遇到個問題,在官方手冊里也沒找到相關說明.....就是當控件標簽一致時,只能獲取到第一個創建標簽名稱控件的值,包括設置值也是一樣;有沒有辦法可以將指定的值給到所有相同
    發表于 04-15 17:42

    歐盟新版ERP 能效標簽EPREL產品注冊

    歐盟新版ERP能效標簽EPREL產品注冊, 2021.5.1開始,supplier可以在歐盟網站的EPREL上,依照新ErP法規(EU) 2019/2015的要求去注冊產品,然后生成新版energy
    發表于 06-26 15:44

    怎樣使用NFC讀卡器讀取T2T標簽

    我正在嘗試使用 NFC 讀卡器讀取 T2T 標簽,Nucleo 擴展板連接到 STM32F103 Nucleo 板。我正在使用 X-CubeExpansion_NFC3 中的示例 這個標簽
    發表于 12-23 06:12

    OrCAD中創建總線及用法詳解

    OrCAD中創建總線及用法詳解,如何創建總線,菜單place->bus或者右側快捷按鈕
    發表于 12-02 10:18 ?2.6w次閱讀

    Synthesis_Place_&_Route

    Synthesis Place & Route
    發表于 02-19 16:48 ?0次下載

    一種基于標簽概率相關性的微博推薦方法

    向微博用戶推薦對其有價值和感興趣的內容,是改善用戶體驗的重要途徑。通過分析微博的特點以及現有微博推薦算法的缺陷,利用標簽信息表征用戶興趣,提出一種基于標簽概率相關性的微博推薦方法LPCMR。首先,該
    發表于 11-17 14:54 ?13次下載
    一種基于<b class='flag-5'>標簽</b>概率<b class='flag-5'>相關</b>性的微博推薦方法

    怎樣在Excel 2013中創建和標記餅圖

    選中“數據標簽”方框,標簽將出現在餅圖中。恭喜,您已經成功創建了帶標簽的餅圖。
    的頭像 發表于 11-22 15:32 ?2863次閱讀

    三菱PLC編程之標簽的設置

    新建工程時選擇了“使用標簽”的情況下,下述標簽將被創建
    發表于 06-25 18:50 ?8396次閱讀

    Chrome 瀏覽器已推出標簽組自動創建功能

    功能可以讓你對標簽頁進行打標簽和分組,可折疊和展開標簽組,消除標簽欄的混亂。 不過,在 Chrome 87 中,谷歌還加入了新的標簽組自動
    的頭像 發表于 11-29 09:35 ?1368次閱讀

    快速了解R-Car Market Place網絡服務

    大家有沒有讀過我去年年底寫的博客“汽車業務的客戶價值(系列17):R-Car聯盟·合作伙伴計劃的介紹”?自這篇博客發布以來,瑞薩收到了大量反饋和在R-Car Market Place創建賬戶的申請。
    的頭像 發表于 12-18 10:57 ?1921次閱讀

    維克多中國榮獲Great Place To Work頒發的認證證書

    近日,維克多中國榮獲由國際著名職場文化評估機構Great Place To Work頒發的認證證書,這一榮譽不僅是對我們長期以來營造的卓越職場文化的肯定,也標志著我們在構建員工滿意度、高效協作的工作環境方面取得了顯著成果。
    的頭像 發表于 03-26 13:32 ?507次閱讀
    主站蜘蛛池模板: 国产精品99AV在线观看| 亚洲熟伦熟女专区| 日本高清免费一本在线观看 | 亚洲AV无码专区国产乱码网站 | 国产毛片女人18水多| 成年人在线视频免费观看| 97在线播放| 最近免费中文字幕大全免费| 永久免费的污视频网站| 亚洲日韩中文字幕区| 亚洲精品久久久久久蜜臀| 18禁无遮遮挡羞漫画免费阅读| 亚洲国产av| 亚洲精品入口一区二区乱麻豆精品 | 综合伊人久久| 中文字幕乱偷无码AV蜜桃| 一边吃奶一边添P好爽故事| 亚洲婷婷天堂综合国产剧情| 亚洲粉嫩美白在线| 亚洲日本激情| 在线观看成人免费| 中文字幕亚洲乱码熟女在线| 最近免费中文字幕大全免费| 99久久免费只有精品| AV色蜜桃一区二区三区| 把腿张开再深点好爽宝贝动态图| 变形金刚7免费观看完整| 国产69精品久久久久乱码| 国产精品97久久AV色婷婷| 国产欧美无码亚洲毛片| 好姑娘社区在线视频| 久久精品动漫99精品动漫| 伦理在线影院伦理电影| 欧美日韩国产高清综合二区| 入禽太深免费高清在线观看5| 视频在线免费观看| 亚洲精品第一综合99久久| 伊人色综合久久天天| 97人妻AV天天澡夜夜爽| 俺也去最新地址| 国产人妻精品无码AV在线五十路 |