s
witch語句根據乙個整數索引值進行多重分支,底層採用跳轉表這種資料結構。跳轉表是乙個陣列,表項i對應**段的位址,當switch索引值等於表項i時採取對應的程式操作。
簡單可理解為:執行
switch時生成乙個長度為最大case常量+1的陣列,程式首先判斷switch變數是否大於最大case 常量,若大於,則跳到default分支處理;否則取得陣列索引號為switch變數值大小,取得陣列對應值即為相應case**塊位址,程式接著跳到此位址執行,完成分支的跳轉。
圖a是乙個簡單的switch例子,對於case值有100、102~104、106;case值102 與 104 是沒有break語句結尾。
圖b是使用c語言的擴充套件形式來描述的,每個表項都是乙個**塊的位址(指標),這裡的「&&」指的就是「&」。
執行switch時,會生成一張跳轉表,表項數為(最大case值-最小case值+1),跳轉表是乙個陣列,陣列是一段連續的記憶體,
jt陣列中包含了7個表項(陣列索引對應值),每個都是指向對應**塊的指標。
編譯器將switch值n-最小case值(100),把取值範圍移動到0至6之間,建立出乙個新的程式變數index。首先判斷index是否大於6,來判斷是否在範圍之外,如果超出直接執行default,即log_def指標對應**塊。否則,根據索引的值直接跳轉不同位置。
執行if-else是逐個條件進行判斷,直到命中;與if-else語句相比,使用跳轉表的優點是執行switch語句的時間與數量無關,且讀取switch引數時只讀取一次,就可跳到對應分支;缺點是維繫了乙個連續的陣列,實際時使用空間換時間。
補充:正因為要將case值轉換為表項i,以及switch值要根據case值轉換為對應陣列索引,所以switch入參時是不支援byte、float、double型,以及對應case分支也是不支援byte、float、double型的。
暫且不說if-else與switch相比哪乙個的執行效率高,先就知道原理後,我們應如何去優化。
if-else
對於if-else,在系統是自上而下逐個條件去判斷,直到命中;所以應將機率大的條件置於最前面。以下給出乙個簡單例子
double random = math.random()*100;//生成0-100的隨機數
if(random > 10)else if(random > 5)else
對於條件機率相等或是條件個數非常多的情況,因為switch的執行時間與條件數量無關,他是根據switch值直接跳轉到對應分支,所以可以選擇switch代替if-else。
switch
對於switch,實際上是根據case最小值與最大值,維繫了一段連續的記憶體空間,以空間換取時間。以下給出乙個簡單的反例,最大值與最小值跨度較大,且之間沒有更多的條件情況,那個無疑實際申請的很多空間是沒用的,所以就應考慮使用if-else在代替。
int random = (int) math.random() * 100;// 生成0-100的隨機數
switch (random)
session的底層執行原理 詳細
判斷客戶端的請求中是否有乙個名字叫做 jsessionid 的cookie,如果沒有 就會新建立乙個session物件,並且將這個session物件的 id 以cookie的形式存放到客戶端,該cookie的 name 叫 jsessionid 如果有 則取出cookie中的session的 id,...
arm64彙編篇 12Switch底層執行原理
1 假設switch語句的分支比較少的時候 例如3,少於4的時候沒有意義 沒有必要使用此結構,相當於if。2 各個分支常量的差值較大的時候,編譯器會在效率還是記憶體進行取捨,這個時候編譯器還是會編譯成類似於if,else的結構。三個及以下case 1.建立工程在main函式頁面寫下如下 void f...
IOS底層原理 5 執行時 2
nslog d nsobject class iskindofclass nsobject class 這裡最終比較的是nsobject類物件的metaclass是不是與其類物件是不是相同,結合類圖所以結果不同 nslog d nsobject class ismemberofclass nsobj...