http://www.javaeye.com/topic/8007?page=1
andyyehoo:
比較一下下面的兩段代碼,說真的,雖然說Java效率低一點可以原諒,不過比較一下這兩段代碼的效率,真是..............雖然java效率比C低n個等級大家都接受了,可是不意味著就可以把系統效率丟到爪哇國去了啊
第一個是直接new一個對象,接著調用一個方法。
第二個是首先getApplicationContext,這個過程就首先不知道耗費多少了。然后是間接的getBean,創建一個對象。接著通過調用3個比reflaction更低效率的方法,設置各個參數,最后是調用。
純粹的比較方法數,已經是第一個的3倍了,更不提每個方法的效率比第一個還慢多少。
當然,第二段的靈活性可能是高很多,但是這樣的靈活性真的需要嘛?在大部分系統的大部分區域,我們需要大量的在EJB,JMS 或者 WEB SERVICE 里面切換嘛?
我們公司的答案不是,所以這個也是我們到現在還不普遍使用spring,而是部分使用spring的原因,也是spring的好處。系統小部分的靈活性需要非常高的部分,我們才利用spring的beanfactory功能,事務控制要求嚴格部分,才使用它的事務管理功能。但是絕大部分,我們不使用。可以說是剛柔并濟吧,不靈活的部分是剛,靈活部分是柔,系統如果全部是柔的話,那就軟綿綿無力了,如果全部是剛的話,那么就太脆而易斷,作為一個真正實用的系統,剛柔還是按80/20原則的好。
引用
UserManager userManager = new UserManager();
String userIDRetured = userManager.addUser("John Smith")
引用
ServiceRequest bsr = this.getApplicationContext().getBean("businessServiceRequest");
bsr.setServiceName("User Services");
bsr.setOperation("addUser");
bsr.addRequestInput("param1", "addUser");
String userIDRetured = (String) bsr.service();
gigix:
andyyehoo 寫道:
比較一下下面的兩段代碼,說真的,雖然說Java效率低一點可以原諒,不過比較一下這兩段代碼的效率,真是..............雖然java效率比C低n個等級大家都接受了,可是不意味著就可以把系統效率丟到爪哇國去了啊
第一個是直接new一個對象,接著調用一個方法。
第二個是首先getApplicationContext,這個過程就首先不知道耗費多少了。然后是間接的getBean,創建一個對象。接著通過調用3個比reflaction更低效率的方法,設置各個參數,最后是調用。
純粹的比較方法數,已經是第一個的3倍了,更不提每個方法的效率比第一個還慢多少。
當然,第二段的靈活性可能是高很多,但是這樣的靈活性真的需要嘛?在大部分系統的大部分區域,我們需要大量的在EJB,JMS 或者 WEB SERVICE 里面切換嘛?
你講這么大一通,我說你純粹扯淡。只要addUser方法里面訪問一次數據庫,你所有那些性能考量全都是白費。哪怕你節約一萬次對象創建和方法調用,連接數據庫的網絡開銷就足以讓你的整個努力化為烏有。你也知道80/20原則,按照80/20原則,J2EE應用根本就不應該考慮性能問題,除非涉及到RPC和I/O操作。你在內存里優化得再好,如果由于架構上的原因多一次RPC調用,整個系統的性能立馬就掉下來了。與其追求這種毫無價值的、微秒級的性能提升,我寧可追求全面的靈活性。
andyyehoo:
gigix 寫道:
你講這么大一通,我說你純粹扯淡。只要addUser方法里面訪問一次數據庫,你所有那些性能考量全都是白費。哪怕你節約一萬次對象創建和方法調用,連接數據庫的網絡開銷就足以讓你的整個努力化為烏有。你也知道80/20原則,按照80/20原則,J2EE應用根本就不應該考慮性能問題,除非涉及到RPC和I/O操作。你在內存里優化得再好,如果由于架構上的原因多一次RPC調用,整個系統的性能立馬就掉下來了。與其追求這種毫無價值的、微秒級的性能提升,我寧可追求全面的靈活性。
addUser調用數據庫的時間,大家都是一樣的,為什么我不能考慮這里調優?
這樣寫,并不會多出一次數據庫或者RPC的調用。除非是很復雜的部分,那么我會考慮局部使用。對于系統80%的代碼,簡單化處理是不會帶來任何問題的。
J2EE應用根本就不應該考慮性能問題?那我所有字符串連接都用+好不好?我做一步catch一次exception好不好?我所有Java方法的調用都通過reflection進行好不好?“根本”這個詞用得太過了。
"我寧可追求全面的靈活性",這個正是問題所在,過分的追求靈活性,將降低效率,我們必須在靈活性和效率中間取得平衡點。xxx說了“添加多一個中間層,可以解決大部分的問題”。中間層越多,當然靈活性約好,但是效率是低了。其實當然,效率這個東西是兩頭大,中間小的一個東西,最耗費時間的,往往是一開始的調用(用戶點擊傳到處理層)和最后的調用(調用數據庫,WEB service),但是這并不意味著,我們就可以無節制的,忽略中間的效率。
gigix:
andyyehoo 寫道
addUser調用數據庫的時間,大家都是一樣的,為什么我不能考慮這里調優?
這樣寫,并不會多出一次數據庫或者RPC的調用。除非是很復雜的部分,那么我會考慮局部使用。對于系統80%的代碼,簡單化處理是不會帶來任何問題的。
你是真不明白呢還是故意抬杠?一次數據庫操作或者RPC的速度是十毫秒級的,通常一個J2EE業務操作包括幾次網絡傳輸和幾次數據庫操作,也就是說在最理想的情況下一個業務操作的速度是百毫秒級甚至秒級的。我請問你,你要節省多少次對象創建、多少次方法調用才能把響應時間提升100毫秒?有個成語可以貼切地形容這種優化:杯水車薪。
andyyehoo 寫道
J2EE應用根本就不應該考慮性能問題?那我所有字符串連接都用+好不好?我做一步catch一次exception好不好?我所有Java方法的調用都通過reflection進行好不好?“根本”這個詞用得太過了。
你還真說對了。我所有字符串連接都是用+;我的業務對象外面有動態代理提供的AOP,也就是說所有方法調用都是通過reflection進行的;我的動態代理里面對異常全部做了包裝,也就是說每個方法調用都有try...catch...的包裹。我得到的效果是什么?更清晰的代碼,更優雅的架構,以及,更容易找到系統的性能瓶頸,更容易優化性能。有些事情也許你沒有聽說過,但不代表它不是真的。
andyyehoo 寫道
"我寧可追求全面的靈活性",這個正是問題所在,過分的追求靈活性,將降低效率,我們必須在靈活性和效率中間取得平衡點。xxx說了“添加多一個中間層,可以解決大部分的問題”。中間層越多,當然靈活性約好,但是效率是低了。其實當然,效率這個東西是兩頭大,中間小的一個東西,最耗費時間的,往往是一開始的調用(用戶點擊傳到處理層)和最后的調用(調用數據庫,WEB service),但是這并不意味著,我們就可以無節制的,忽略中間的效率。
同樣一個問題,我換另一個角度來問你:你要做多少次字符串連接,才能浪費100毫秒時間?你可以自己寫個程序,對比一下StringBuffer.append和String.+的性能差距,看看需要多大的字符串才能讓你損失100毫秒。如果你能告訴我這個結果,我一定很有興趣知道。別忘了,100毫秒僅僅是一次普通J2EE業務操作整體響應時間的數十分之一而已。
andyyehoo:
引用:
你還真說對了。我所有字符串連接都是用+;我的業務對象外面有動態代理提供的AOP,也就是說所有方法調用都是通過reflection進行的;我的動態代理里面對異常全部做了包裝,也就是說每個方法調用都有try...catch...的包裹。我得到的效果是什么?更清晰的代碼,更優雅的架構,以及,更容易找到系統的性能瓶頸,更容易優化性能。有些事情也許你沒有聽說過,但不代表它不是真的。
lol: 我相信你的系統是這樣的,但是不代表所有的系統都需要象你這樣。對于很多中小型系統來說,如此優雅的架構并不都是必須的。
而且,你這樣對開發的效率有影響,代碼量又多啦,呵呵,對開發人員總體素質的要求也高了不少,公司的成本又高囖。 這些都是需要考慮的。:evil:
當然,我承認后一種方法的先進性和靈活性,但是,還是那個問題,不需要拿牛的殺雞,而現在的市場,雞還是比牛多一些。
gigix:這也是你的想當然。如果采用一個優雅的架構,普通程序員只需要編寫面向對象的程序就足夠了。他不需要考慮如何管理事務,他不需要考慮如何記錄日志,他甚至不需要考慮如何獲得和關閉數據庫連接,而且他寫的每個模塊都可以從系統中摘出來單獨測試。難道開發這樣的程序會更慢、寫更多的代碼、對開發人員要求更高?相反,如果做太多代碼級的優化,勢必損害架構的優雅和靈活,會導致更多的重復代碼,會使得各個模塊耦合緊密而不能獨立測試,那樣的系統才是代碼量更多、對開發者要求更高的。
我只舉一個最簡單的例子。你認為如果我們需要一個UserManager,那么就直接new UserManager()好了。但是這樣一來,開發client代碼的人就無法只測試他自己的業務邏輯,他的單元測試還必須同時兼顧UserManager的邏輯。我請問你,這是不是比寫一個mock來測試自己這一個模塊有更高的難度?一旦UserManager修改了實現,它的作者必須與所有使用者溝通,以保證這些人的單元測試不會失敗,這是不是增加了工作量降低了開發效率?如果client代碼能夠這樣寫:
[code:1]
public class MyClass {
private UserManager _um;
public void setUserManager(UserManager um) {
_um = um;
}
public void doSomething() {
_um.doSomething();
}
}
[/code:1]
編寫client的人不必考慮該創建UserManager的哪個實現類,也不必考慮如何創建,也不必關心這個對象的生命周期,也不用管它是本地對象還是RPC stub。難道這樣寫程序不是更輕松、代碼量更少、對程序員的要求更低嗎?
andyyehoo:
gigix寫道:
這也是你的想當然。如果采用一個優雅的架構,普通程序員只需要編寫面向對象的程序就足夠了。他不需要考慮如何管理事務,他不需要考慮如何記錄日志,他甚至不需要考慮如何獲得和關閉數據庫連接,而且他寫的每個模塊都可以從系統中摘出來單獨測試。難道開發這樣的程序會更慢、寫更多的代碼、對開發人員要求更高?相反,如果做太多代碼級的優化,勢必損害架構的優雅和靈活,會導致更多的重復代碼,會使得各個模塊耦合緊密而不能獨立測試,那樣的系統才是代碼量更多、對開發者要求更高的。
在正規公司里面,分工明確的話,都是專人寫好架構,普通程序員按照架構往里面填代碼就是的啦。正常情況下,他也是不需要如何管理事務,記錄日志,獲得和關閉連接,每個模塊也可以單獨測試。
但是,程序調試出錯的時候,他們也需要自己查看日志,考慮一下各方各面的因素才能調試,按照第二種寫法,無疑,這些程序員的素質要相對高一些,考慮的問題更多一些,才能進行調試的。
gigix寫道:
我只舉一個最簡單的例子。你認為如果我們需要一個UserManager,那么就直接new UserManager()好了。
這個是例子這么寫的,需要靈活的部分,我們自然會用其它方法寫。不過在最簡單的情況中,我們是會這么寫,更簡單的情況,直接還調用靜態方法,不會不給吧,呵呵
gigix:
andyyehoo 寫道
這個是例子這么寫的,需要靈活的部分,我們自然會用其它方法寫。不過在最簡單的情況中,我們是會這么寫,更簡單的情況,直接還調用靜態方法,不會不給吧,呵呵 :lol:
別的不多說,就說這一件事好了。我要求所有程序員嚴格遵循“針對接口編程”的原則,每個組件必須提供一個接口和一個實現,獲得組件必須以接口的形式、通過dependency injection獲得。而按照你的說法,你要求程序員在提供功能時有時針對接口編程,有時針對對象編程,有時靜態方法實現,也就是說你要求程序員清楚這三種設計的語義區別和利弊權衡。我想請問你,究竟是誰對程序員的要求更高呢?
andyyehoo:
引用
別的不多說,就說這一件事好了。我要求所有程序員嚴格遵循“針對接口編程”的原則,每個組件必須提供一個接口和一個實現,獲得組件必須以接口的形式、通過dependency injection獲得。
佩服佩服,沒有程序員抗議嘛?
引用
有時針對接口編程,有時針對對象編程,有時靜態方法實現,也就是說你要求程序員清楚這三種設計的語義區別和利弊權衡。
我們現在是這樣,不過,這個好像是JAVA程序員的基本功吧,雖然現在很多程序員基本功不好,那樣的話,還是我們要求高點,按照你那樣寫的話,都快可以機器產生代碼了,呵呵,可以考慮開始向自動產生代碼發展了。
不過嘛,還是那個問題,出了bug,你們調試還是比較困難點吧?
gigix:
andyyehoo 寫道
別的不多說,就說這一件事好了。我要求所有程序員嚴格遵循“針對接口編程”的原則,每個組件必須提供一個接口和一個實現,獲得組件必須以接口的形式、通過dependency
injection獲得。
|
有時針對接口編程,有時針對對象編程,有時靜態方法實現,也就是說你要求程序員清楚這三種設計的語義區別和利弊權衡。
|
我們現在是這樣,不過,這個好像是JAVA程序員的基本功吧,雖然現在很多程序員基本功不好,那樣的話,還是我們要求高點,按照你那樣寫的話,都快可以機器產生代碼了,呵呵,可以考慮開始向自動產生代碼發展了。
不過嘛,還是那個問題,出了bug,你們調試還是比較困難點吧?
對象怎么創建、對象的生命周期怎么管理,這些都是跟業務沒關系的infrastructure。讓程序員可以不操心這些infrastructure,一心關注自己的業務邏輯,怎么會有人抗議?
你說“調試比較困難”,我就真的很懷疑你究竟有多少經驗了。任何一個有經驗的J2EE開發者都會知道,OOD做得越好,debug越輕松。OOD做得好,你才可能做出完備的單元測試,然后用單元測試快速鎖定debug的范圍。我們調試比較困難嗎?我真的不知道該怎么回答這個問題,因為我已經好久沒開過debugger了。
andyyehoo:
引用
你說“調試比較困難”,我就真的很懷疑你究竟有多少經驗了。任何一個有經驗的J2EE開發者都會知道,OOD做得越好,debug越輕松。OOD做得好,你才可能做出完備的單元測試,然后用單元測試快速鎖定debug的范圍。我們調試比較困難嗎?我真的不知道該怎么回答這個問題,因為我已經好久沒開過debugger了。
所指的bug,是指需要在spring的配置,aop搭建的事務控制,日志中穿梭尋找的bug,不過這個對于你來說應該是很熟了,所以沒什么感覺了,一樣快速鎖定了。應該就是良好的架構使這定位個過程很快的。反正有固定步法的話,走7步和走5步差不多吧,呵呵。
gigix:
andyyehoo 寫道
你說“調試比較困難”,我就真的很懷疑你究竟有多少經驗了。任何一個有經驗的J2EE開發者都會知道,OOD做得越好,debug越輕松。OOD做得好,你才可能做出完備的單元測試,然后用單元測試快速鎖定debug的范圍。我們調試比較困難嗎?我真的不知道該怎么回答這個問題,因為我已經好久沒開過debugger了。
|
所指的bug,是指需要在spring的配置,aop搭建的事務控制,日志中穿梭尋找的bug,不過這個對于你來說應該是很熟了,所以沒什么感覺了,一樣快速鎖定了。應該就是良好的架構使這定位個過程很快的。反正有固定步法的話,走7步和走5步差不多吧,呵呵。
這些事情更不需要debug,因為它們都在冒煙測試的范圍內。只要一開始測試通過,你做了一件事以后變得不通過了,馬上就可以知道是你剛才的改動造成了破壞。這里沒有5步、7步的調試,只有1步:回退你上一分鐘做的修改。
說起來,好象你也開始贊成:OOD和良好的架構才是真正重要的,而不是20毫秒的性能提升。
andyyehoo:
引用
說起來,好象你也開始贊成:OOD和良好的架構才是真正重要的,而不是20毫秒的性能提升。
:lol: 我一直的觀點是,OOD和良好的架構當然很重要的,但是要根據項目選擇合適靈活的架構,而不必全部采用最靈活的系統,而在這個基礎上,“20毫秒的性能提升”,也是需要考慮的事情之一,而不可以完全拋之腦后。
突然想到A計劃2成龍說的,我不能接受任何人,以國家民族利益的崇高名義,草菅任何無辜市民的生命。(記不太清,大概)哈哈,有點象