switch...case && if...else效率比較和優化
以前一直都是在程式設計中,用switch...case和if....else混合一起使用。但是我個人的習慣是如果可以,我都會盡量使用switch語句進行條件判斷。這隻能說是個人習慣吧,以前也一直沒有想很多,只是單純的覺得比起if語句,使用switch可以簡化我的輸入,而且後面我在審視自己的程式碼的時候也會覺得比較容易讀懂。
最近小學期上課的時候,是一位公司的老師給我們上課,我觀察了一下他的程式碼習慣,他傾向比較多的條件判斷的時候,就使用switch,但是在小範圍的條件判斷中,他比較喜歡用if,我覺得這其中應該是有一定道理的,突然想起之前我在看《高效能javascript》的時候,作者也提出了這方面的優化。特此重新回顧了一下之前的書裡的內容,結合網上大牛們的解釋,做一次歸納總結吧。
使用if-else還是switch,最流行的方法是基於測試條件的數量來判斷:條件數量越大,越傾向於使用switch而不是if-else。這通常歸結於程式碼的易讀性。這個觀點認為,當條件較少時,if-else更易讀,當條件較多時,使用switch更加易讀。--《高效能javascript》
之後,我在維基百科也搜了一下switch_statement的有關資料,關於它的Compilation,維基百科作出瞭如下的解釋:
也就是說,在編譯器中,它會將一系列的語句編譯成分支表,然後在判斷時,無需像if-else語句一樣一個個進行邏輯判斷,而是通過在case裡的值,對值進行搜尋,從而達到對搜尋的優化。我也在知乎搜尋了一下,但是發現不知道是不是我開啟方式有問題,關於這方面的解釋比較少,或者說。。問題太簡單了。。。然後我找到了如下作者的回答(如果涉及侵權請聯絡我,我將立刻刪除,謝謝。)
switch通過編譯成一個分支表來達到優化的目的,我個人感覺是通過空間的代價來換取時間。說完了switch...case,現在我們再來對比一下if-else,沒有對比就沒有傷害。它和switch不同,if-else語句會對一個個條件按順序進行查詢,直到找到符合條件的"入口"。也因為這個特性,所以,當條件數量很大,它和switch的差距就慢慢顯現出來了。
事實證明,大多數情況下switch比if-else允許得要快,但只有當數量條件很大時,才快得明顯。當條件增加的時候,if-else效能負擔增加的程度比switch明顯得多。因此我們傾向於在條件數量比較少的情況下使用if-else,而在條件數量較大的時候使用switch,出於效能考慮,這是合理的。--《高效能javascript》
我個人的使用習慣是,當只有涉及到true||false的時候,我才會傾向於使用if-else語句,如果涉及到常數,或者數值的判斷,我一般傾向於使用switch,事實證明,這種做法也是對的,出於對程式碼的可讀性也好,出於效能考慮來說,我覺得我的使用習慣好像是正確的。
但是這本書中,有提及對if-else的優化:
最小化到達正確分之前所需要判斷的條件數量,最簡單的方式是將最可能的出現的條件放在首位........if-else語句應該總是按照最大概率到最小概率的順序排序,或者,最小化條件判斷的次數,使用巢狀的方式等。
但是我個人傾向於,程式碼的易讀性,如果一味地使用巢狀,其實只會影響程式碼的可讀性。
查詢表【補充方案】
其實有時候優化條件語句的最佳方案是避免使用if-else和我switch,當有大量的離散數值時,查詢表的優勢就會慢慢體現出來,查詢表這整個過程就變成了資料查詢或者物件成員的查詢了。
當單個key和value之間存在有邏輯對映關係是,查詢表的優勢就會體現出來。一個查詢表可以看做是一個陣列或者一個物件,通過索引操作來取代邏輯運算,由於這樣子的對映關係,可以讓執行效率提高。
查詢表最主要的優點是,不用任何條件判斷語句,即使候選值增加,也不會有額外的效能開銷。switch語句比較適合每個key都需要有獨特對應一個或者一系列的動作的時候。
關於switch...case && if...else效率比較和優化就到這裡了,一切共勉。本文仍存在很多不足,希望各位加以指點~謝謝。
# 補充於 2018-05-09
拋開我們所說的記憶體也好,效率也好,如果讓我來總結這兩個判斷的一個異同點,我更傾向於用使用場景和你解釋,我們更傾向於用 if 去判斷連續的區間 用 switch 去判斷離散分佈的可能取值,也就是說:
if 比較適用的場景是 目標點 落在某一個區間 例如 90 < x <100 之類的
switch 比較適用的場景是 x = blue .... x = red ..... 之類的處理場景
推薦閱讀:
相關文章
- 淺談優化if...else優化
- mysql的left join和inner join的效率對比,以及如何優化MySql優化
- js 深比較和淺比較JS
- PHP 5.6,7.0,7.1,7.2 和 HHVM 執行效率比較PHP
- SQL、NoSQL和NewSQL的優缺點比較SQL
- 【MyBatis】幾種批量插入效率的比較MyBatis
- 訪問vector元素方法的效率比較
- 併發程式設計:DEMO:比較Stream和forkjoin框架的效率程式設計框架
- Oracle date 型別比較和String比較Oracle型別
- not in 和 not exists 比較和用法
- Laravel 和 Spring Boot 兩個框架比較創業篇(一:開發效率)LaravelSpring Boot框架創業
- etcd和redis比較Redis
- TCP和UDP比較TCPUDP
- Redis 和 Memcached 比較Redis
- Java和JavaSciprt比較Java
- Go和Python比較的話,哪個比較好?GoPython
- 優先佇列的比較器佇列
- kookeey、Luminati 和 Smartproxy 海外代理的特點和優缺點分析比較
- HashMap,LinkedHashMap,TreeMap讀取大量資料效率的比較HashMap
- Java位元組流檔案複製及效率比較Java
- 比較器-Comparable和Comparator
- ImageMagic 和 GraphicsMagick 的比較
- ArrayList和LinkedList的比較
- PyTorch和TensorFlow比較 - thegradientPyTorch
- ==和equals方法的比較
- Webpack打包效率優化篇Web優化
- Apache與Nginx的優缺點比較ApacheNginx
- Apache與Nginx的優缺點、效能比較,到底選擇哪個比較好?ApacheNginx
- JavaScript 匿名函式與具名函式執行效率比較JavaScript函式
- ECode1024 | String拼接方法concat與+效率比較問題
- Go 與 C++ 的對比和比較GoC++
- Transformer和MoE架構比較ORM架構
- Java 中 Comparable 和 Comparator 比較Java
- TreeMap和HashMap的元素比較HashMap
- 比較Windows和Linux SQL容器WindowsLinuxSQL
- Python:如何風騷而又不失優雅的使用Switch...CasePython
- 分享幾個比較提高工作效率的軟體
- powershell中的where和foreach比較
- 檔案和影像比較工具Kaleidoscope