通過字節碼看if-else和switch-case

2021-01-07 愛遊蕩的技術人

條件語句是我們使用非常頻繁的語法之一,其中if-else和switch-case最為常用,那很多同學也會有疑惑,這兩種方式有什麼區別,哪個效率更高一些呢。接下來我們就從字節碼的角度,看看這兩種方法的實現。

先來看看if-else。

從代碼字面上理解,應該是自上而下,以此判斷,那到底是不是呢,看看字節碼。

iload_1將變量(i)推至棧頂,iconst_1將第一個整型常量(1)推至棧頂。

然後通過if_icmpne來判斷這兩個值是否相等,如果相等,就執行列印,然後跳轉到第42行,結束(下同),如果不相等,就跳轉至第15行。15行這次是取出第二個常量(2)去和 i 做比較,如果不相等,跳轉至第30行,取出第三個數值(3)去和 i 做比較,如果不相等,跳轉到第42行,結束。

從字節碼看,確實if-else是順序判斷,直到找到符合條件的。

那switch-case又是怎樣工作的呢?

先大概講一下,switch-case會創建一個table,每條case的值,作為key,對應著這個條件要跳轉到的指令行。

table有兩種,tableswitch和lookupswitch,每個條件的值之間的比較連貫的,會使用tableswitch,否則會使用lookupswitch,而且lookupswitch會對所有的case的值進行排序,保證是有序的,這樣可以提高查找效率。

接下來看例子。

1,2,4,6這是四種條件分支,不連續,但是間隔較小,所以JVM會使用tableswitch,看看字節碼是什麼樣。

先看看tableswitch的內容,我們發現,比我們的四種數據多了兩種,把1~6之間的缺少的值,補充了進去,形成一個連續的表。它們對應的指令行都是80,那第80行是什麼呢?其實就是default語句那一個分支。因為補充的這兩個在代碼中是不存在的,所以就讓它指向default就行了。

當判斷時,系統會判斷你輸入的值是否在1~6之間,如果不在,就直接跳到default,如果在,那就定位就好了,所以需要是一個連續的table。table中每一個數值後面對應這要跳轉到的指令行,根據key取到行號,跳就是了。

40,50,60,70分別對應這每個條件的列印代碼,執行完後,跳轉到87(return)。

下面我們把條件的值改一下,讓它的間隔大一些。

我們的順序是10,50,30,看看字節碼。

系統使用了lookupswitch,而且,它的排序是10,30,50,是按照升序排列的,變成了有序的。也沒有像tableswitch那樣,填充間隔,所以它們的查找方式是不一樣的。

因為是有序的,所以可以採取諸如二分法的算法,來提高查找效率。

理解力兩種條件語句的實現方式,那麼該如何選擇呢?

如果條件簡單而且比較少if-else也沒問題,畢竟switch-case要生成一個table,佔用了一定的空間,如果條件多,if-else不但不美觀,而且順序執行的效率也是比較低的。所以這時候採用switch-case是合理的。

相關焦點

  • 揭秘::switch...case為什麼比if...else執行效率高?
    在C語言中,條件判斷語句是程序的重要組成部分,也是系統業務邏輯的控制手段,教科書告訴我們switch...case...語句比if...else if...else執行效率要高,但這到底是為什麼呢?本文嘗試從彙編的角度予以分析並揭曉其中的奧秘。
  • 沒人比我更懂if-else和switch-case
    if-else與switch-case既生瑜,何生亮。邏輯上,真的if-else可以搞定switch-case的事,但是你看看下面的代碼。這個其實C語言有規定:else始終與同一括號內最近的未匹配的if語句結合。如果你是初學者,也不要去鑽這牛角尖,浪費時間。建議1:寫if-else語句時,記得加上{和},別偷懶!
  • switch case 的運用
    對於這種情況,實際開發中一般使用 switch 語句代替,請看下面的代碼:#include <stdio.h>int main(){int a;printf("Input integer number:");scanf("%d",&a);switch(a){case 1
  • switch和if else語句到底用誰
    是在簡單if語句的基礎上添加對立的條件else語句 比如下面的代碼:通過條件1來判斷是否需要執行語句1,如果條件1為真,則直接執行語句1;反之為假,則執行語句2。但是不管執行語句1或者語句2,語句3都會執行雙分支if語句中需要時刻了解其else的取值範圍。
  • if快還是switch快?解密switch背後的秘密
    重要程度和使用頻率更是首屈一指,那我們要如何選擇 if 還是 switch 呢?他們的性能差別有多大?switch 性能背後的秘密是什麼?接下來讓我們一起來尋找這些問題的答案。switch VS if我在之前的文章《9個小技巧讓你的 if else看起來更優雅》中有提過,要儘量使用 switch 因為他的性能比較高,但具體高多少?
  • [GO語言基礎] 五.順序控制語句和條件控制語句(if、else、switch)
    這篇文章將詳細講解順序控制語句和條件控制語句。這系列文章入門部分將參考「尚矽谷」韓順平老師的視頻和書籍《GO高級編程》,詳見參考文獻,並結合作者多年的編程經驗進行學習和豐富,且看且珍惜!後續會結合網絡安全進行GO語言實戰深入,加油~這些年我學過各種程式語言,從最早的C語言到C++,再到C#、PHP、JAVA,再到IOS開發、Python,到最新的GO語言,學得是真的雜。
  • 編程入門第六課,交換語句(switch,case)
    今天福哥會給童鞋們講講交換語句(switch,case)的使用方法,交換語句適合對一個變量的值等於不同內容的時候進行不同處理的情況。其實來說交換語句(switch,case)完全可以通過條件語句(if)來替代,不過使用交換語句可以有更高的執行效率,還可以讓代碼結構看起來更加清晰,所以如果情況適合的時候福哥還是推薦使用交換語句來編寫代碼2.
  • Python條件判斷語句詳解:if、else、switch都有了
    如果所有的表達式都不成立,則程序執行else子句的代碼。其中的else子句可以省略,表達式兩側的括號也可以省略。下面【例3-2】中的這段代碼通過判斷學生的分數,確定學生成績的等級。switch(表達式) {    case 常量表達式1: 語句1    case 常量表達式2: 語句2    …    case 常量表達式n: 語句n    default: 語句m}switch語句表示的分支結構比if…elif…else語句更清晰,代碼可讀性更高,但是Python並沒有提供switch語句,而是可以通過字典實現
  • 5分鐘學會如何在Python中實現Switch-case
    由於簡單的語法和複雜的句法短語,該語言已成為各種科學應用的標準,如機器學習。機器學習Switch語句雖然Java和PHP等流行語言都有內置的switch語句,但您可能會驚訝地發現Python語言沒有。因此,您可能會嘗試使用一系列if-else-if塊,對switch語句的每種情況使用if條件。但是,由於跳轉表,switch語句比if-else-if梯形圖快得多。它不是按順序評估每個條件,而只需要查找一次計算的變量/表達式,然後直接跳轉到相應的代碼分支來執行它。
  • Java基礎之switch-case 語句
    case 常量表達式2:        語句2;        break;    default:        語句;}通過switch(表達式)來接受參數,再通過case來比較,如果傳入的參數等於case後的就執行該判斷後的語句。
  • Python實現switch/case用法案例
    —— Pandas的DataFrame如何按指定list排序—— Python的條件分支語句switch/case如何實現基本用法# 引入pandas的數據類型「category」,從而進行排序。# python中沒有switch case語句。
  • C語言經典分析:"switch" VS "if...else"
    可能覺得寫出來的代碼比較優雅,不過也有部分人喜歡用if...else覺得這樣的話代碼比較容易閱讀且簡單。    /***具體分析分析***/    1)對於一般的程式設計師可能用switch的比較少的原因:        1、switch的case必須是整形,這樣對於很多浮點的比較判斷等比較麻煩;        2、switch的每個條件都會配break;(除非多個選項同時在一起處理可以不用
  • Python中如何實現Switch/Case語句?
    我們通過一個示例看。將數字1,2,3,4映射為Spring,Summer,Fall,Winter,而其它數字映射為Invalid Season。Java代碼中可以用Switch/Case語句來實現:public static String getSeason(int season) { String SeasonName = ""; switch (season) { case 1:      SeasonName = "Spring"; break;
  • 這道考 switch 控制語句的阿里基礎面試題你能答對嗎?
    如果既沒有 case 語句和表達式的值匹配上,也沒有 default 語句,那就沒有什麼搞的了,switch 語句執行了個寂寞,也算是正常完成。其實到這裡,上面的第一點不就是《碼出高效Java開發手冊》後面的面試題的場景嗎?
  • Java中有趣的switch,你不知道的switch用法-第14節
    大家好,我是你的老師父,上一篇講了if和else分支,那這次講講switch分支控制。注意case中是不能寫變量的,必須是常量舉個例子,看下圖:上邊通過System.in接收控制臺輸入,上一篇文章已經詳細講解過System.in了。那接收到輸入值之後可以轉換為int類型。轉換完成後,作為switch中的變量,根據此變量的具體值來決定到底去執行那個case中的邏輯。
  • 是時候和else關鍵字說再見了……
    但是如果A是二進位變量的集合,或者包含著更大的變量,出現問題的機會就可能會出乎意料的大,且難以理解、測試和維護。避免if/else if,只使用if語句,花時間確保if組的輸入條件是互斥的,這樣答案就不依賴於執行順序了。
  • switch 語句
    1. switch 語句形式switch 語句的一般形式:switch(表達式) {case
  • R語言決策結構,if語句,if..else語句
    當使用if,else if, else語句時要注意幾點。if語句可以有零個或一個else,但如果有else if語句,那麼else語句必須在else if語句之後。if語句可以有零或多else if語句,else if語句必須放在else語句之前。當有一個else if條件測試成功,其餘的else...if或else將不會被測試。
  • 代碼中那麼多「煩人」的if else
    100 : 60;4、合併條件表達式在項目中有些邏輯判斷是可以通過梳理和歸納,變更為更簡單易懂的邏輯判斷代碼,如下所示。7、梳理優化判斷邏輯和第 4 點比較類似,我們可以通過分析 if else 的邏輯判斷語義,寫出更加易懂的代碼,例如以下這個嵌套判斷的優化。
  • 在 js 開發中,如何減少 if else 語句的使用
    並不是說 if else 多就不好,關鍵是看用的地方,jQuery.fn.init 裡除了 if else 判斷簡潔點,難道要改成 switch?就算用工廠模式,還不是得做大量的if判斷。代碼整潔強迫症患者必須要來個拋磚引玉:1.if(a為真){    a=a}else{    a=b}可寫成:a = a || b2.