效能永遠不是優先考慮的問題
在SAE部落格上看到一篇文章,摘錄有價值的段落存檔,收藏。
我從來不會一開始就考慮效能問題。如果專案成本很低,甚至到專案結束時,如果沒有感覺到明顯的效能問題,也不會去管。要知道現在已經不是DOS的年代,CPU的計算能力很高,但成本很低了。重要一點是,如果只針對提升效能對程式碼做改動,很容易破壞程式碼的複用性和可維護性。而返過來,提高了程式碼的複用性和可維護性,則很容易提高效能。
下面有一個PHP的程式碼例項,功能是幫助使用者重置密碼(程式碼為了簡單說明問題,請不要太在意一些無關的細節)requestResetPassword是接收使用者重置密碼的請求並且做了相應的檢查。為了更好的複用性,我將重置密碼的操作單獨分配到一個新的resetPassword的函式,更改完密碼的後再呼叫sendEmail向使用者傳送一封通知郵件。
/**
* 使用者請求重置密碼的接收器
*/
function requestResetPassword() {
//檢查使用者是否存在
if( !checkUserExists( $_GET[`userid`] ) ) {
exit(`抱歉,使用者不存在,請確認使用者帳號。`);
}
resetPassword( $_GET[`userid`] );
//最後向使用者傳送一封郵件
sendEmail( $_GET[`userid`], `重置密碼成功`, `新的密碼是xxxx` );
exit(`新密碼已經傳送到你的郵箱。`);
}
/**
* 幫助使用者重置密碼
*/
function resetPassword( $userid ) {
//檢查使用者是否存在
if( !checkUserExists( $userid ) ) {
return false;
}
//進行重置使用者密碼的操作
//略...
return true;
}
/**
* 向使用者傳送一封郵件
*/
function sendEmail( $userid, $title, $content ) {
//檢查使用者是否存在
if( !checkUserExists( $userid ) ) {
return false;
}
//傳送郵件操作
//略...
return true;
}
/**
* 檢查某個使用者是否存在
*/
function checkUserExists( $userid ) {
$user = getUserInfo( $userid );
return !empty( $user );
}
/**
* 獲取某個使用者的資料
*/
function getUserInfo( $userid ) {
//假設我有一個query的函式,它用來查詢資料庫並返回資料
$user = query( "SELECT * FROM `user` WHERE `uid`=" . intval( $userid ) );
return is_array( $user ) ? $user : array() ;
}
現在問題是,這三個函式都同時使用checkUserExists這個函式來檢查使用者不存在,資料庫查詢了三次,這樣帶來了一些額外的開銷。
如果要去掉三者之間任意一個checkUserExists,看上去是可能的。但是如果之後有某些功能要呼叫resetPassword或者sendEmail,使用者不存在時,系統可能會發生錯誤。
還有一個解決方法是,將resetPassword的邏輯寫到requestResetPassword裡,再過一點,把sendEmail的邏輯也寫進去。這樣函式呼叫減少,資料庫查詢也變成一次了,效能得到了提高。但是重置密碼和傳送郵件的功能將不能得到複用,並且違背了單一責任的原則,程式碼複雜度也提高了。
不過,因為函式分離和複用性都很好,如果實際效能受到影響,可能考慮用快取的方法減少資料庫查詢,我改動了它們共用的checkUserExists函式:
/**
* 檢查某個使用者是否存在
*/
function checkUserExists( $userid ) {
//增加一個快取,用以記錄檢查使用者的結果
static $cache = array();
//檢查當前使用者是否已經檢查過一次
if( isset( $cache[ $userid ] ) ) {
return $cache[ $userid ];
}
$user = getUserInfo( $userid );
//把結果記錄到快取中
$cache[ $userid ] = !empty( $user );
return $cache[ $userid ];
}
也可以用同樣的方法改動getUserInfo函式。
這裡可以看到,當程式碼的複用性提高時,想提高效能是很簡單的,效能的瓶頸也很容易被發現和修改。
儘管這個例子對效能影響還不夠大,還有一些影響更大的,比如說遍歷,我可能為了複用而將遍歷封裝到一個函式中,並且多次使用它。這些開銷對我的專案根本沒有預想中那樣有太大的影響,或者說是微乎其微的。所以我更願意把時間花在如何提高程式碼的複用性和維護性方面,而不是糾結於浪費多這一點效能。實際效能如果真的達不到要求,也可以權衡增加硬體配置。
個人經驗
我是很同意文中觀點的,比如平時在專案中會經常使用foreach遍歷list陣列,陣列長度一般不會超過幾十個,這樣只是理論上對效能有影響,實際根本感覺不到。
我還是期待開發出有更多人使用的產品,那時再調整優化效能就顯得意義更大。用簡約的技術實現最大的效益。
甘於平凡
程式設計師真的很高傲,在我接觸過的人中,包括我自己也是。我以前經常對一些簡單的程式碼感到不屑,而總想在專案中寫一些犀利的程式碼,讓人看起來很NB,但結果總是和想象差太遠,程式碼總是寫的很差,邏輯也不夠清晰。歸根到底,是我帶著這樣的思想去寫程式碼,而忽略了程式設計的根本:解決問題。現在我改掉了這個壞毛病,以解決問題為目的去程式設計,以簡單為主。出乎意料的是別人有時會對我說,這裡的程式碼寫得很棒。
踏實的做事,會有意想不到的收穫。
參考:
http://blog.sae.sina.com.cn/archives/657
http://www.php.net/manual/zh/function.is-array.php
http://cn2.php.net/manual/zh/function.exit.php
相關文章
- Bazaarvoice:2/5的歐洲消費者優先考慮環保問題
- 優先考慮型別安全的異構容器型別
- 使用 DevSecOps 優先考慮產品安全性dev
- YouGov:52%的中國人優先考慮應用的安全性Go
- 企業需要優先考慮移動統一通訊
- 2.5.11.2 FORCE LOGGING 模式需要考慮的效能問題模式
- 冰汽時代:最冰冷的,永遠不是溫度
- 為什麼企業選擇ERP系統時會優先考慮SAP?
- 為什麼模切企業選擇ERP系統會優先考慮點晴?
- AI並非無所不能,製造業數字化轉型優先考慮成本AI
- 記一個效能優化問題優化
- 為什麼模切企業選擇ERP系統時會優先考慮點晴
- Setapp:57% 的 Mac 使用者在購買新應用程式的時候會更優先考慮安全APPMac
- YouGov:半數美國人認為政府購車計劃應優先考慮排放量Go
- 永遠考慮那個擁有更強寫作能力的程式設計師程式設計師
- iOS問題整理08----效能優化iOS優化
- MySQL問題定位-效能優化之我見MySql優化
- Android效能優化——效能優化的難題總結Android優化
- 記一次Prometheus代理效能優化問題Prometheus優化
- 由一次KPI考慮到的問題KPI
- MySQL複製效能優化和常見問題分析MySql優化
- QtWebEngine效能問題QTWeb
- 集合效能問題
- 【Github】 Github訪問不是私密連線問題Github
- 關於 Puerts 的效能問題
- 效能測試瓶頸之CPU問題分析與調優
- Shiro效能優化:解決Session頻繁讀寫問題優化Session
- 前端技術分享:頁面效能優化問題覆盤前端優化
- iOS使用Instrument Time Profiler工具分析和優化效能問題iOS優化
- 2019: 程式設計師只有一半智商,看問題,永遠都只是一半程式設計師
- 收集的一些React hooks的效能優化以及閉包陷阱問題ReactHook優化
- 現在生意不是能不能幹的問題
- 再見了Antirez永遠的Redis之神Redis
- 請問新建話題是不是有問題?版主幫忙看看
- 兩個小問題深入淺出List的效能問題
- 技能篇:linux服務效能問題排查及jvm調優思路LinuxJVM
- 中戲開設“戲劇人工智慧”專業,首招2名博士生!優先考慮對戲劇感興趣的理工考生人工智慧
- 【譯】精挑細選的一份React效能問題優化的清單React優化