姓名:周桐 學(xué)號:15020120101? 轉(zhuǎn)載自:https://www.huxiu.com/article/279050.html
【嵌牛導(dǎo)讀】:眾多網(wǎng)友對 C++20 發(fā)布持消極態(tài)度
【嵌牛鼻子】:C++20特點? 編程?
【嵌牛提問】:C++20存在哪些不足厨喂?
【嵌牛正文】:
本文來自微信公眾號:Info(ID:Qinfoqchina)揉忘,編輯:Lisa
C++ 20 要來了!然而翅楼,大家都不看好是怎么回事兒乎赴?
為了 C++20忍法,C++ 標(biāo)準(zhǔn)委員會曾舉辦歷史上規(guī)模最大的一次會議(180 人參會),試圖通過會議確定哪些特性可以加入新版本榕吼,我們也已經(jīng)看到媒體爆料的部分新特性缔赠,比如 Concepts、Ranges友题、Modules嗤堰、Coroutimes 等,但大部分開發(fā)人員并不認可此次調(diào)整度宦,并將部分新特性歸結(jié)為“語法糖”踢匣。
不少網(wǎng)友看到上述特性紛紛在社交平臺吐槽,表示不看好 C++20 版本的發(fā)布:
不僅國內(nèi)如此戈抄,國外的一位游戲領(lǐng)域開發(fā)人員接連在社交平臺發(fā)表看法离唬,聲明自己不看好 C++20 的新特性,并認為新版本沒有解決最關(guān)鍵的問題划鸽,他通過使用畢達哥拉斯三元數(shù)組示例對 C++20 標(biāo)準(zhǔn)下的代碼和舊版本進行對比输莺,明確闡述自己對于 C++20 的態(tài)度戚哎。
畢達哥拉斯三元數(shù)組,C ++ 20 Ranges 風(fēng)格
以下是 C++20 標(biāo)準(zhǔn)下代碼的完整示例(超長預(yù)警):
以下代碼為簡單的 C 函數(shù)打印第一個 N Pythagorean Triples:
如果不必修改或重用此代碼嫂用,那么一切都沒問題型凳。 但是,如果不想打印而是將三元數(shù)組繪制成三角形或者想在其中一個數(shù)字達到 100 時立即停止整個算法嘱函,應(yīng)該怎么辦呢甘畅?
畢達哥拉斯三元數(shù)組,簡單的 C ++ 風(fēng)格
以下是舊版本的 C++ 代碼實現(xiàn)打印前 100 個三元數(shù)組的完整程序:
我們可以編譯這段代碼:clang simplest.cpp -o outsimplest往弓,需要花費 0.064 秒疏唾,產(chǎn)生 8480 字節(jié)可執(zhí)行文件,在 2 毫秒內(nèi)運行并打印數(shù)字(使用的電腦是 2018 MacBookPro函似,Core i9 2.9GHz槐脏,Xcode 10 clang):
(3,4,5)
(6,8,10)
(5,12,13)
(9,12,15)
(8,15,17)
(12,16,20)
(7,24,25)
(15,20,25)
(10,24,26)
...
(65,156,169)
(119,120,169)
(26,168,170)
這是 Debug 版本的構(gòu)建,優(yōu)化的 Release 版本構(gòu)建:clang simplest.cpp -o outsimplest -O2撇寞,編譯花費 0.071 秒准给,生成相同大小(8480b)的可執(zhí)行文件重抖,并在 0ms 內(nèi)運行(在 clock()的計時器精度下)。
接下來祖灰,對上述代碼進行改進钟沛,加入代碼調(diào)用并返回下一個三元數(shù)組,代碼如下:
這幾乎在同一時間編譯和運行完成局扶,Debug 版本文件變大 168 字節(jié)恨统,Release 版本文件大小相同。此示例編寫了 pytriples 結(jié)構(gòu)三妈,每次調(diào)用 next() 都會跳到下一個有效三元組畜埋,調(diào)用者可隨意做任何事情,此處只調(diào)用一百次畴蒲,每次打印三聯(lián)悠鞍。
雖然實現(xiàn)的功能等同于三重嵌套 for 循環(huán),但 C++ 20 標(biāo)準(zhǔn)下的代碼讓人感覺不是很清楚模燥,無法立即讀懂程序邏輯咖祭。如果 C ++ 有類似 coroutine 的概念,就可能實現(xiàn)三元組生成器蔫骂,并且和原始的 for 循環(huán)嵌套一樣清晰:
C ++20 Ranges 會讓整段代碼更加清晰嗎么翰?結(jié)果如下:
多次 return 實在是讓人感覺很奇怪,這或許不應(yīng)該成為好語法的標(biāo)準(zhǔn)辽旋。
C++ 存在的問題有哪些浩嫌?
如果談到 C++ 的問題檐迟,至少有兩個:
一是編譯時間;
二是運行時性能码耐。
雖然 C++ 20 Ranges 還未正式發(fā)布追迟,但本文使用了它的近似版,即 isrange-v3(由 Eric Niebler 編寫)伐坏,并編譯了規(guī)范的“Pythagorean Triples with C ++ Ranges”示例:
該代碼使用 0.4.0 之后的版本怔匣,并用 clang ranges.cpp -I. -std=c++17 -lc++ -o outranges 編譯,整個過程花費 2.92 秒桦沉,可執(zhí)行文件為 219 千字節(jié)每瞒,運行在 300 毫秒之內(nèi)。
這是一個非優(yōu)化的構(gòu)建纯露,優(yōu)化構(gòu)建版本(clang ranges.cpp -I. -std=c++17 -lc++ -o outranges -O2)在 3.02 秒內(nèi)編譯剿骨,可執(zhí)行文件為 13976 字節(jié),并在 1ms 內(nèi)運行埠褪。因此運行時性能很好浓利,可執(zhí)行文件稍大,編譯時問題仍然存在钞速。
C++20 比簡單版本的代碼編譯時間長近 3 秒
編譯時是 C ++ 的一個大問題贷掖,這個非常小的例子編譯時間比簡單版的 C ++ 長 2.85 秒。在 3 秒內(nèi)渴语,現(xiàn)代 CPU 可以進行大量操作苹威,比如,在 Debug 構(gòu)建中編譯一個包含 22 萬行代碼的數(shù)據(jù)庫引擎(SQLite)只需要 0.9 秒驾凶。所以牙甫,編譯一個簡單的 5 行示例代碼比運行完整的數(shù)據(jù)庫引擎慢三倍?
在開發(fā)過程中调违,C ++ 編譯時間一直是大小代碼庫的痛苦根源窟哺。他認為,C ++ 新版本應(yīng)該把解決編譯時問題排在第一位技肩。但是且轨,整個 C++ 社區(qū)好像并不知道該問題枪向,每個版本都將更多內(nèi)容放入頭文件老客,甚至放入必須存在于頭文件的模板化代碼中。
range-v3 是 1.8 兆字節(jié)的源代碼诀艰,全部在頭文件中雳锋,因此黄绩,雖然使用 C++ 20 輸出 100 個三元數(shù)組的代碼示例只有 30 行,但加上頭文件后玷过,編譯器最終會編譯 102,000 行代碼爽丹。在所有預(yù)處理之后筑煮,簡單版本的 C ++ 示例只有 720 行代碼。
調(diào)試構(gòu)建性能差
Ranges 示例的運行時性能慢了 150 倍粤蝎,這對于要解決實際問題的代碼庫而言真仲,兩個數(shù)量級的速度可能意味著不會對任何實際數(shù)據(jù)集起作用。該開發(fā)者在游戲行業(yè)工作初澎,這意味著引擎或工具的 Debug 版本不適用于任何真實的游戲級別模擬(性能無法接近所需的交互級別)秸应。
通過避免 STL 位(提交),可以讓最終運行時快 10 倍碑宴,也可以讓編譯時間更快且調(diào)試更容易软啼,因為微軟的 STL 實現(xiàn)特別喜歡深度嵌套的函數(shù)調(diào)用。這并不是說 STL 必然不好延柠,有可能編寫 STL 實現(xiàn)在非優(yōu)化版本中不會變慢 10 倍(如 EASTL 或 libc ++ 那樣)祸挪,但由于微軟的 STL 過度依賴深度嵌套,因此會變慢贞间。
作為語言的使用者贿条,大部分人不關(guān)心它是否正確發(fā)展!即便知道 STL 在 Debug 中太慢增热,寧愿花時間修復(fù)或者研究替代方案(例如不使用 STL整以,重新實現(xiàn)需要的位,或者完全停止使用 C ++)也不會花時間整理論文上報 C++ 委員會峻仇,這太浪費時間公黑。
其他語言如何?
這里簡要介紹 C#中“畢達哥拉斯三元數(shù)組”實現(xiàn)础浮,以下是完整 C#源代碼:
就個人而言,C5旖荆可讀性較高:
用 C ++:
C#LINQ 的另一種“數(shù)據(jù)庫較少”的形式:
在 Mac 上編譯這段代碼豆同,需要使用 Mono 編譯器(本身是用 C#編寫的),版本 5.16含鳞。mcs Linq.cs 需要 0.20 秒影锈。相比之下,編譯等效的簡單 C#版本需要 0.17 秒蝉绷。LINQ 樣式為編譯器創(chuàng)建了額外的 0.03 秒鸭廷。但是,C ++ 卻創(chuàng)造了額外的 3 秒熔吗。
一般來說辆床,我們會試圖避免大部分 STL,使用自己的容器桅狠,哈希表使用開放尋址代替...... 甚至不需要標(biāo)準(zhǔn)庫的大部分功能讼载。但是轿秧,難免需要時間說服每一位新員工(尤其是應(yīng)屆生),因為 C++20 被稱為現(xiàn)代 C ++咨堤,很多新員工認為“新一定就是好”菇篡,其實并不是這樣。
為什么 C ++ 會這樣一喘?
該開發(fā)者表示不太清楚 C++ 為什么會發(fā)展到現(xiàn)在這個地步驱还。 但他個人認為,C++ 社區(qū)需要學(xué)會“保持接近 100%向后兼容的同時發(fā)展一種語言”凸克。 在某種程度上议蟆,現(xiàn)在的 C++ 生態(tài)系統(tǒng)太專注于炫耀或證明其價值的復(fù)雜性,卻并不易用触徐。
在他的印象中咪鲜,大多數(shù)游戲開發(fā)人員還停留在 C++ 11、14 或者 17 版本撞鹉,C++20 基本忽略了一個問題疟丙,無論什么被添加到標(biāo)準(zhǔn)庫,編譯時間長和調(diào)試構(gòu)建性能差的問題沒有解決都是無用的鸟雏。
對于游戲產(chǎn)業(yè)而言享郊,大部分傳統(tǒng)技術(shù)是用 C 或 C ++ 構(gòu)建的,在很長一段時間內(nèi)孝鹊,沒有出現(xiàn)可行的替代品(好在目前至少可以用 Rust 作為可能的競爭者)炊琉,對 C 和 C ++ 的依賴程度很高,需要社區(qū)的一些幫助和回應(yīng)又活。
本文來自微信公眾號:Info(ID:Qinfoqchina)苔咪,編輯:Lisa
*文章為作者獨立觀點,不代表虎嗅網(wǎng)立場
本文由?InfoQ?授權(quán)?虎嗅網(wǎng)?發(fā)表柳骄,并經(jīng)虎嗅網(wǎng)編輯团赏。轉(zhuǎn)載此文請于文首標(biāo)明作者姓名,保持文章完整性(包括虎嗅注及其余作者身份信息)耐薯,并請附上出處(虎嗅網(wǎng))及本頁鏈接舔清。原文鏈接:https://www.huxiu.com/article/279050.html?