看板 C_and_CPP 關於我們 聯絡資訊
僅就我能回應的部份回應,畢竟我也沒什麼料。 ※ 引述《guest0079 (火辣辣的大姊姊)》之銘言: :  一般認為C++效能較差是有幾點現實上的考量: :  a. C++太多太雜太難掌握,讓程式人員浪費太多時間在語言本身而非問題的最佳解上 這和程式的效能無關。如果你要說的是 C++ 的某個語言特性使得實作某些演算 法變得很困難,請舉出具體實例,而且你還要證明用 C 實作會比較簡單。 : b. C++會偷偷增加一些程式碼來維持本身的OO特性,一不小心就多出了不必要的code : c. C++會偷偷增加一些程式碼來維持運算子過載特性,一不小心就多出了不必要的code 同上,請就這兩點舉出具體實例並證明同樣的功能在 C 中並不會造成額外負擔。 :  d. 用C++物件導向實作的函式庫,很方便使用沒錯,但代價就是負擔太大(如Qt) 所以負擔是什麼?同樣的功能用 C 實作可以快多少? : e. ...應該還有很多我不知道的 : 2.C++程式不易讀 : 運算子過載真是太好用了,而且程式一看就懂,真是太好維護了,但是如果… :   Man a_man("大雄"); // 定義一個男人 :   Woman a_woman("靜香"); // 定義一個女人 : int money = MAX_VALUE; :   printf("幹這是什麼鬼:%s", a_man + money + a_woman); :  這種code要怎麼維護?先回頭找一下Man與Woman中operator + 的定義 :  再確認與int作運算表示什麼,再查一下書看看運算的順序的先後關係,如果operator :  中又用到其他operator的過載,又要再去查,為了追一個問題,又引起n個問題,為 :  了確認n個問題,又出現n^2個問題…沒完沒了。程式很簡潔沒錯,但是要怎麼debug? :  難道每一行程式都要猜猜看嗎? 所以改用 C 的寫法是像這樣囉? printf("幹這是什麼鬼:%s", Add_Something_Woman( Add_Man_Int(a_man, money), a_woman) ); 也不是不行啦,只是有天你發現 int 不夠用要改成 long 的時候,麻煩就很 大了。而且你一樣也是要去看 Add_xxxx 這些 function 的內容才知道他們 做了什麼事,而且這些 function 也會用到其它 function,debug 起來並不 會比較簡單。 另外你自己也說了,「運算子過載真是太好用了,而且程式一看就懂」。這意 味著如果你會寫出自己看不懂的 code,那你就不該用 operator overloading。 你可能會說,這是某個「自以為很厲害的人」寫出的 code,你不得不用,那 可能是以下的情況: 1. 大家都看不懂,只有「自以為很厲害的人」看得懂 code。 這種情況當然是「自以為很厲害的人」該死。 2. 一半的人看得懂,另外一半看不懂。請你們在下次技術團隊會議時好好 討論要不要改做法。 3. 大家都看得懂,你看不懂。很不幸的,這種情況下是你該多念點書。 : 好的物件導向遠比C好維護,不過C++決對不是好的物件導向語言(這句話一言難盡) : 3.物件導向不適合底層程式 : 了解物件導向的人就知道,它是較貼進人類思維的程式寫作方法,反之,它就不是 :  一個貼近底層機器運作原理的編程原則,機器語言、組語才是最貼近底層運作機制的 :  語言,想要用OO來描述機器的行為、自然法則、各式各樣的protocol…等等諸如此類 :  的運作機制容易流於天馬行空,任意妄為。如果硬要用物件導向來實作底層機制,可 :  能十個人有十二種不同的見解,沒人看得懂彼此的程式,因為每個人對機制的感受都 :  不一樣,物件結構的分析各有各的看法,沒完沒了。 :  當然,不用物件導向也是可以寫C++程式,但那還不如用C來的單純 :  (但個人偏愛用完全無繼承機制的物件架構來寫C++,來當作是C的加強版) 就我的認知,物件導向的目的並不是要貼近人類的思維,而是為了軟體易於維護 並擴充功能。所以如果對一個系統該如何設計,若是每個程式設計師都有自己的 意見,那當然是坐下來好好討論哪一個做法比較容易維護、擴充。 當然,程式設計師意見不合是常有的事,但並不如你所想象的那樣是天馬行空的 爭論,而是而實際地考慮各種設計在維護及擴充上的優劣。 : 4.C++的複雜度太高 :  C公認的聖經只有一本,內文也才兩佰多頁,一本C++的入門書就一仟多頁(C++ Primer) : C++的功能及其運作細節多如牛毛,寫了10年的程式也許還會看到自已不懂的語法,或是 : debug時發現某個平常不會注意的細節在作怪,這如果只是開發一般的AP還好,如果是開 : 發OS這種大型、不易物件化的程式時,事情就大條了。因為: : a.開發人員太多,每人都用一種冷門的技巧,那要trace code就要買十本C++在身邊才行 : b.總有人喜歡賣弄技巧,喜歡來個多重繼承,自行定義運算子,把程式的複雜度弄得很高 :  自以為很強,等到程式成長到自已無法控制(可能久了也忘了)才雙手一攤說:比爾蓋茲 :  對不起,我要去Google上班了 : c.自已乖一點不要寫出太複雜的程式就好了嗎?不!因為C++支援太多種技巧、style, :  所以有時候不得不乖乖配合別人的程式風格,想維持單一模組風格的一致性也很因難 : OS不是少數幾個人就能寫出來的程式,一定要有不少人力來大量的分工才能完成 : ,但高度的分工之後又必需維持緊密的偶合關係,是一項複雜度很高,極易失敗的專案 : ,如果再用一個複雜度相對較高的C++工具來寫的話,就難上加難了 團隊開發本來就應該要先統一好 coding style,此外像是類別應該要有什麼行 為、提供哪些 method、哪些東西使用 template,則是在設計階段就應該訂好, 如果有某個程式設計師喜歡搞怪不合作,那換用 C 他還是可以完全不合作。 為了避免使用者濫用,程式語言不應該提供太多複雜的功能嗎?那 C 應該先把 指標拿掉。 #define 也應該要拿掉,不然有人會寫出下面這種東西: #define begin { #define end } : 最後,我很好奇某人說:C++的sort大勝C的qsort,理由何在? qsort 每次對元素進行比較的時候,都要透過 function pointer 去呼叫 compare function。如果你學過 computer architecture 就會了解,使用 function pointer 會比一般的 function call 還慢,尤其 function 的 內容很短的時候,這個額外的負擔就占了很大的比例。 因為 C++ 的 sort 是 function template,是在 compile time 就把靜 態的 function call 插進 sort 裡面,而且若 compare function 很短, 還可以得到 inline 的好處,進一步省掉 function call 的成本,當然 會比 C 的 qsort 快上不少。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.121.115.112 ※ 編輯: littleshan 來自: 59.121.115.112 (03/07 13:40) ※ 編輯: littleshan 來自: 59.121.115.112 (03/07 13:41)
guest0079:感謝你的意見分享,晚點再來與你討論 03/07 15:18
Ebergies:我認為 guest 的意思是既然 OO 不可避免要產生 overhead 03/07 15:21
Ebergies:那乾脆選個不容易 OO 的語言 03/07 15:21
Ebergies:如同 public member 總有人要偷用, 那就宣告成 private 03/07 15:22
tinlans:「『不可避免』要產生 overhead」? 03/07 15:26
Ebergies:我不想爭這個... XD 一個 virtual function 你的質疑就倒 03/07 15:28
tinlans:原來用 virtual function 是不可避免的,不寫會生病死掉。 03/07 15:30
Ebergies:沒有 virtual 你如何 polymorphism? 還要問別的嗎? 03/07 15:31
Ebergies:問到最後還算 OO 嗎? 03/07 15:31
tinlans:當你在 C 有使用 virtual function 相同需求時,你一樣要 03/07 15:31
tinlans:重新實作跟 virtual function 一樣的東西。 03/07 15:31
Ebergies:不要跟我說你的 OO 只是一個 class 然後有 method 03/07 15:31
Ebergies:放棄掉 OO 就不一定要實作 virtual function 一樣的東西 03/07 15:32
tinlans:我的 OO 可以搭不是 OO 的東西在一起,所以不會不可避免。 03/07 15:33
Ebergies:甚至有的 virtual function 是為了做 factory 用的 03/07 15:33
tinlans:沒有人規定一個 class 所有 member function 都是 virtual 03/07 15:34
Ebergies:我的 OO 可以搭不是 OO 的東西在一起 <= 那我們有牴觸嗎 03/07 15:34
tinlans:OO 搭了不是 OO 的東西只是「非純 OO」,不是「非 OO」。 03/07 15:35
Ebergies:另外我的重點在 "有人" 會亂用, 既然如此乾脆直接避掉 03/07 15:36
tinlans:我看過好多人亂用 pointer 耶,為了避掉大家改用 Java 吧 03/07 15:36
Ebergies:避掉 OO 不會降 performance, 避掉 C 用 JAVA 就... 03/07 15:37
tinlans:但是避掉 OO 會提高你軟體維護的成本。 03/07 15:39
tinlans:結果就是,現在純 C 的程式也免不了使用 OO。 03/07 15:40
Ebergies:但是今天沒有人在談軟體維護的成本啊... 03/07 15:40
tinlans:所以台灣沒有軟體工業存在,因為普遍無法正視事實。 03/07 15:41
Ebergies:不過就我所知... 台灣軟體公司幾乎都是 C++ 的 code 耶.. 03/07 15:42
tinlans:現在的使用者需求越來越大,程式越寫越大,哪可能免維護。 03/07 15:43
Ebergies:呃... 你是不是離題了 XDD 03/07 15:43
tinlans:那都是號稱 C++ 的 code,打開 source code 看就知道。 03/07 15:43
tinlans:核心還是圍繞你第二和第三行的推文啊,我只是在說明為什麼 03/07 15:44
tinlans:不「乾脆選個不容易 OO 的語言」。 03/07 15:44
Ebergies:問題是第二第三行的推文是針對作業系統核心... = =a 03/07 15:45
tinlans:若 p 則 q;破 p 可以使命題無效,破 q 可否定命題。 03/07 15:45
tinlans:作業系統核心也是需要 OO 的,因為需要維護啊。 03/07 15:46
tinlans:很多人被教科書騙了以為 OO 就是要跟現實物體 1 : 1 呈現 03/07 15:46
Ebergies:問題是它的複雜跟 OO 與不 OO 沒很大的關係 03/07 15:47
tinlans:,讀過比較深的 OO 書籍都會知道那些說法只是為了讓你懂。 03/07 15:47
tinlans:有複雜的轉型和依賴 union 的地方通常都可以用 OO 漂亮的 03/07 15:48
tinlans:解決掉,而且不會產生額外負擔,因為你 C 原本就那樣寫。 03/07 15:48
tinlans:實作相同的功能,C++ 帶來的額外負擔是 C 寫就存在的。 03/07 15:49
Ebergies:我覺得你沒有搞懂話題 (逃) 03/07 15:51
Ebergies:你說的大都是正確的 03/07 15:51
tinlans:OO 當初被設計出來不是為了「讓寫程式的人比較直覺」。 03/07 15:52
tinlans:只是因為手動維護 type code、union、function pointers 03/07 15:52
tinlans:其實有很多風險存在,語言提供 OO 機制反而是綁住你讓你不 03/07 15:53
tinlans:能太自由去亂搞。 03/07 15:53
Ebergies:但問題在於 "有人" 會因為 C++ 方便的功能做出不好的東西 03/07 15:53
tinlans:事實上,kernel 甚至其它軟體的複雜度常常是這些東西帶來 03/07 15:54
tinlans:的,所以 C++ 才會避免「有人」亂設 function pointers, 03/07 15:54
tinlans:避免「有人」亂填 type code,避免「有人」亂用 union 欄 03/07 15:55
tinlans:位。 03/07 15:55
tinlans:C 寫出比 C++ 危險的東西比率高得多了,C++ 聖經本都講過 03/07 15:56
Ebergies:你講的部分是"維護"的不好, 我說的是"效能"的不好 03/07 15:56
Ebergies:而且沒有人在跟你說用 C 寫東西比較不危險啊老大... 03/07 15:56
tinlans:我 15:48 - 15:49 那三行不是說了,C 寫成那樣效能也一樣 03/07 15:57
tinlans:,但是比較危險。 03/07 15:58
tinlans:重點是,C 真的有那樣的東西存在於 kernel source code。 03/07 15:58
tinlans:你用 C++ 的 OO 機制寫,是 compiler 幫你產生等效的程式 03/07 15:59
Ebergies:你為什麼要忽略一開始的推文呢?... 03/07 15:59
tinlans:碼,效率上不會比較差,但是又比較安全。 03/07 16:00
tinlans:你一開始的推文不是說明為什麼乾脆選個不容易 OO 的語言嗎 03/07 16:01
Ebergies:我不想從 virtual function 那行又重新再講一遍... 03/07 16:02
tinlans:,既然 kernel 有 OO 可以漂亮解決的程式碼,又不會損失效 03/07 16:02
tinlans:能,又比較安全,你為什麼不用? 03/07 16:03
tinlans:我也不想從手動維護 type code、union、function pointer 03/07 16:03
tinlans:這邊重講一遍。 03/07 16:03
H45:請問可以回文嗎....雙方論點我抓不太到 03/07 16:03
Ebergies:我沒有反駁你這邊喔 03/07 16:03
tinlans:還是你認為手動維護這些東西帶來的效能損失比 virtual 03/07 16:04
tinlans:function 少? 03/07 16:04
Ebergies:我是說 C++ 提供這些東西, 就有人會亂用 03/07 16:04
tinlans:你第二行強調 overhead,15:56 強調「效能」。 03/07 16:05
Ebergies:C 亂寫會當機, 會不容易維護, C++ 亂寫比較不會當機 03/07 16:05
Ebergies:但 C++ 亂寫帶來的 performance down 比較大, 可以理解吧 03/07 16:06
tinlans:亂用的部分我也用容易維護和比 C 不易犯錯回你了啊。 03/07 16:06
tinlans:........所以當機比 performance down 來得好嗎? 03/07 16:07
tinlans:我推薦 Intel 的 vTune,用過它你就會知道這根本不是問題 03/07 16:07
Ebergies:但是作業系統雖然 care 當機,但要寫得很安全效能又差太多 03/07 16:07
tinlans:,那是一套很強的效能分析器,跑下去你就知道問題在哪了。 03/07 16:07
Ebergies:變成你要用 C++ 寫還是會寫成 C 的形式 03/07 16:08
tinlans:不,C 也為了讓它安全付出不少代價,這些可以無償跟 OO 換 03/07 16:08
tinlans:我不否認用 C++ 寫 kernel 時常要以純 C 形式撰寫,但它的 03/07 16:09
tinlans:OO 機制卻可以在適當時機發揮效用。 03/07 16:10
Ebergies:你是指 attack 的安全還是 bug 方面的安全? 03/07 16:10
tinlans:我們不是光就當機這件事為前提討論是否安全嗎? 03/07 16:10
Ebergies:所以, 應用軟體大多使用 OO 了不是嗎? 03/07 16:10
tinlans:跟 UI 接近的地方主要使用 OO 是沒錯的,C++ 在 lib 層偏 03/07 16:11
tinlans:好的是靜態多型而非動態多型。 03/07 16:11
Ebergies:所以最後 release 的結果還是會以純 C 比較好對吧 03/07 16:12
tinlans:純 C 不是最好的,OO 適用的地方在於「功能抽換」以及模組 03/07 16:13
tinlans:跟外界溝通的邊界上。 03/07 16:13
Ebergies:這我也很同意啊 = = 03/07 16:13
tinlans:你可以比較 C++ 寫的 kernel 跟 C 寫的 kernel 其易讀性和 03/07 16:14
tinlans:效能,世界上又不是沒有 C++ 寫的 kernel。 03/07 16:14
Ebergies:我所謂選擇 C 的原因並不是 C++ 寫不出好效能 03/07 16:16
Ebergies:而是 C++ 容易寫出不好的效能 03/07 16:16
tinlans:我知道你說的是 C++ 「不小心」會寫出效能不好的東西。 03/07 16:16
Ebergies:那我們剛剛是在搞笑嗎... ... 03/07 16:17
tinlans:不過我倒是不認為有本事用 C++ 寫 kernel 的人會這麼呆。 03/07 16:17
tinlans:工廠裡把幾百萬的機具搞壞的員工,理由是他嫌操作手冊太多 03/07 16:19
Ebergies:我以為是只要有心人都可以寫 kernel... ... =口= 03/07 16:19
tinlans:,這個理由你會接受嗎? 03/07 16:19
tinlans:你擔心的事情只會駐留在某個時間點上,當一個人辛辛苦苦用 03/07 16:20
tinlans:C++ 寫出 kernel 卻發現效能不好時,他會去查原因還是直 03/07 16:21
tinlans:接用 C 重寫一遍? 03/07 16:21
Ebergies:如果寫人都是天才, 那基本上... 應該是沒什麼差啦... 03/07 16:21
tinlans:就算寫的人是個笨蛋,隨著時間的演進,他也會聰明起來。 03/07 16:22
Ebergies:等等~~~ 離題了 XDD 不過我還是可以回答你: 查原因 03/07 16:22
Ebergies:但查到最後可能會改掉架構, 然後發現不用 OO 03/07 16:22
Ebergies:結果最後居然能用 C compile (大驚!!?) 03/07 16:23
tinlans:但是你忽略了當他拋棄 OO 之後可能遇到的新問題。 03/07 16:24
tinlans:我也遇過拋棄 OO 改用 C 寫才發現 OO 可貴之處的人啊 XD 03/07 16:24
Ebergies:... = = 我從以前到現在一直是用 OO 在寫程式啊... = = 03/07 16:25
tinlans:很多東西在沒有瞭解需求的當下是不知道它的優點和用處的。 03/07 16:25
Ebergies:尤其了解 patterns 以後覺得 OO 更是可貴 03/07 16:25
tinlans:那你有沒有遇過用純 C 為了某個「彈性」和「安全性」手刻 03/07 16:26
tinlans:個半死之後才發現那其實根本就是 OO 的前身(劣化版) 結果 03/07 16:26
tinlans:幹得要死的情形呢? 03/07 16:26
Ebergies:想到 "彈性" 應該直覺就會想到 OO 吧... 我倒是沒這經驗 03/07 16:27
tinlans:有人是繞了一圈才體會到其實所謂的 overhead 根本不存在。 03/07 16:28
Ebergies:但是我還是要說追求效率時你會很想把那些彈性全都拆掉... 03/07 16:28
tinlans:他當初之所以用 OO 就是考量到這些,結果發現效能不佳丟掉 03/07 16:28
Ebergies:有一好無兩好就是這樣 03/07 16:28
tinlans:OO,結果用純 C 刻出一樣的東西來,結果發現效能也一樣。 03/07 16:29
Ebergies:因為刻一樣的東西表示 OO 的概念仍然在只是用 C 實作吧 03/07 16:29
tinlans:......然而現實是,少了彈性會讓 user 哭,偏偏 kernel 的 03/07 16:30
tinlans:user 就是最難搞的 programmer。 03/07 16:30
tinlans:可以用 OO 改寫又效能無損的 C 有兩大類:1. 根本就是 OO 03/07 16:32
tinlans:2. OO 書籍上最詬病的那些寫法 03/07 16:33
tinlans:2. 是回你 16:29 說的部分,說明狀況不只有 1. 而已。 03/07 16:34
tinlans:無論你怎麼走,requirement 還是長那個樣子擺在那邊。 03/07 16:35
Ebergies:哈哈哈 XD 所以以前 linux 難用有一部分就是這樣啊 03/07 16:35
tinlans:捨棄 requirement 奔向 performance 的懷抱,結果就是被 03/07 16:37
tinlans:user (programmer) 罵到臭頭。 03/07 16:38
weiyucsie:我怎麼覺得吵這麼多 不如實際改寫看看比較實際XD 03/07 17:03
weiyucsie:看看實際上會遇到的困難 以及在各方面的比較 03/07 17:04
weiyucsie:不過感覺sort那種東西 有點trade off就是了(速度/大小) 03/07 17:05
weiyucsie:(不過應該是部分改寫 全部改寫太累了XD) 03/07 17:21
bugmans:改寫比較難,筆戰比較簡單 03/07 18:33
yoco315:典型的 Java 言論 XD 03/07 20:09