亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++性能剖析教程之switch語句

2020-05-23 13:26:57
字體:
來源:轉載
供稿:網友

前言

幾乎每本面向初學者的C語言或C++書籍在前面兩章都會提到分支控制語句if……else和switch……case,在某些情況下這兩種分支控制語句可以互相替換,但卻很少有人去深究在if……else和switch……case語句的背后到底有什么異同?應該選擇哪一個語句才能使得效率最高?要回答這些問題,只能走到switch語句的背后,看看這些語句到底是怎么實現的。

基本格式

switch語句的基本格式如下:

switch (表達式) {
case 常量表達式1:《語句序列1》《break;》 //《》中的內容可省
……
case 常量表達式n:《語句序列n》《break;》 //同上,下同
《default:語句序列》
}

其中:

  • 表達式——稱為“條件表達式”,用作判斷條件,取值為整型、字符型、布爾型或枚舉型。
  • 常量表達式——由常量構成,取值類型與條件表達式相同。
  • 語句序列——可以是一個語句也可以是一組語句。

if語句與switch語句

相信學過C/C++的同學對這兩個語句的異同早就了如指掌,if語句作為條件判斷,滿足條件進入if語句塊,不滿足條件則進入else語句塊,而且if和else語句塊又可以繼續嵌套if語句。switch則是通過判斷一個整型表達式的值來決定進入到哪一個case語句中,如果所有case條件都不滿足則進入到default語句塊。

//簡單的if語句if (a == 1) i = 1;else if (a == 2) i = 2;else i = 3;
//簡單的switch語句switch (a){ case 1: i = 1; case 2: i = 2; default: i = 3;}

編譯器如何實現switch語句?

現在編譯器已經足夠智能和強大,經過測試,g++實現switch語句的方式就至少有三種,編譯器會根據代碼的實際情況,權衡時間效率和空間效率,去選擇一個對當前代碼而言綜合效率最高的一種。

編譯器實現switch語句的三種方式:

  • 逐條件判斷
  • 跳轉表
  • 二分查找法

后面我們將就這三種實現方法適用的代碼場景進行測試和分析。

1. 逐條件判斷法

逐條件判斷法其實就是和if……else語句的匯編實現相同,編譯器把switch語句中各個case條件逐個進行判斷,直到找到正確的case語句塊。這種方法適用于switch語句中case條件很少的情況,即使逐個條件判斷也不會導致大量時間和空間的浪費,比如下面這段代碼:

#include <algorithm>int test_switch(){ int i ; int a = std::rand(); switch(a){  case 0: i = 0;break;  case 1: i = 1;break;  case 2: i = 2;break;  default: i = 3;break; } return i;}

該代碼對應的匯編代碼如下:

 movl -4(%rbp), %eax cmpl $1, %eax je .L3 cmpl $2, %eax je .L4 testl %eax, %eax jne .L8 movl $0, -8(%rbp) jmp .L6.L3: movl $1, -8(%rbp) jmp .L6.L4: movl $2, -8(%rbp) jmp .L6.L8: movl $3, -8(%rbp) nop

eax寄存器存儲的是判斷條件值(對應于C++代碼中的a值),首先判斷a是否等于1,如果等于1則跳轉到.L3執行a==1對應的代碼段,然后判斷a是否等于2,如果等于2則跳轉到.L4執行a==2對應的代碼段……可能難理解的是第6行代碼testl %eax, %eax,其實這只是編譯器提高判斷一個寄存器是否為0效率的一個小技巧,如果eax不等于0則跳轉到.L8代碼段,執行default代碼段對應的代碼,如果eax等于0則執行a==0對應的代碼段。

由上面對編譯器生成匯編代碼的分析,我們可以發現:編譯器在這種情況下使用逐個條件判斷來實現switch語句。

2. 跳轉表實現法

在編譯器采用這種switch語句實現方式的時候,會在程序中生成一個跳轉表,跳轉表存放各個case語句指令塊的地址,程序運行時,首先判斷switch條件的值,然后把該條件值作為跳轉表的偏移量去找到對應case語句的指令地址,然后執行。這種方法適用于case條件較多,但是case的值比較連續的情況,使用這種方法可以提高時間效率且不會顯著降低空間效率,比如下面這段代碼編譯器就會采用跳轉表這種實現方式:

#include <algorithm>int test_switch(){ int i ; int a = std::rand(); switch(a){  case 0: i = 0;break;  case 1: i = 1;break;  case 2: i = 2;break;  case 3: i = 3;break;  case 4: i = 4;break;  case 5: i = 5;break;  case 6: i = 6;break;  case 7: i = 7;break;  case 8: i = 8;break;  case 9: i = 9;break;  default: i = 10;break; } return i;}

該代碼對應的匯編代碼如下:

 movl -4(%rbp), %eax movq .L4(,%rax,8), %rax jmp *%rax.L4: .quad .L3 .quad .L5 .quad .L6 .quad .L7 .quad .L8 .quad .L9 .quad .L10 .quad .L11 .quad .L12 .quad .L13 .text.L3: movl $0, -8(%rbp) jmp .L14.L5: movl $1, -8(%rbp) jmp .L14#后面省略……

在x64架構中,eax寄存器是rax寄存器的低32位,此處我們可以認為兩者值相等,代碼第一行是把判斷條件(對應于C++代碼中的a值)復制到eax寄存器中,第二行代碼是把.L4段偏移rax寄存器值大小的地址賦值給rax寄存器,第三行代碼則是取出rax中存放的地址并且跳轉到該地址處。我們可以清楚的看到.L4代碼段就是編譯器為switch語句生成的存放于.text段的跳轉表,每種case均對應于跳轉表中一個地址值,我們通過判斷條件的值即可計算出來其對應代碼段地址存放的地址相對于.L4的偏移,從而實現高效的跳轉。

3. 二分查找法

如果case值較多且分布極其離散的話,如果采用逐條件判斷的話,時間效率會很低,如果采用跳轉表方法的話,跳轉表占用的空間就會很大,前兩種方法均會導致程序效率低。在這種情況下,編譯器就會采用二分查找法實現switch語句,程序編譯時,編譯器先將所有case值排序后按照二分查找順序寫入匯編代碼,在程序執行時則采二分查找的方法在各個case值中查找條件值,如果查找到則執行對應的case語句,如果最終沒有查找到則執行default語句。對于如下C++代碼編譯器就會采用這種二分查找法實現switch語句:

#include <algorithm>int test_switch(){  int i ;  int a = std::rand();  switch(a){    case 4: i = 4;break;    case 10: i = 10;break;    case 50: i = 50;break;    case 100: i = 100;break;    case 200: i = 200;break;    case 500: i = 500;break;    default: i = 0;break;  }  return i;}

改代碼段對應的匯編代碼為:

    movl -4(%rbp), %eax cmpl $50, %eax je .L3 cmpl $50, %eax jg .L4 cmpl $4, %eax je .L5 cmpl $10, %eax je .L6 jmp .L2.L4: cmpl $200, %eax je .L7 cmpl $500, %eax je .L8 cmpl $100, %eax je .L9 jmp .L2

代碼第二行條件值首先與50比較,為什么是50而不是放在最前面的4?這是因為二分查找首先查找的是處于中間的值,所以這里先與50進行比較,如果eax等于50,則執行case

50對應代碼,如果eax值大于50則跳轉到.L4代碼段,如果eax小于50則繼續跟4比較……直至找到條件值或者查找完畢條件值不存在??梢钥闯龆植檎曳ㄔ诒3至溯^高的查詢效率的同時又節省了空間占用。

總結

何時應該使用if……else語句,何時應該使用switch……case語句?

通過上面的分析我們可以得出結論,在可能條件比較少的時候使用if……else和switch……case所對應的匯編代碼是相同的,所以兩者在性能上是沒有區別的,使用哪一種取決于個人習慣。如果條件較多的話,顯而易見switch……case的效率更高,無論是跳轉表還是二分查找都比if……else的順序查找效率更高,所以在這種情況下盡量選用switch語句來實現分支語句。當然如果我們知道哪種條件出現的概率最高,我們可以將這個條件放在if判斷的第一個,使順序查找提前結束,這時使用if……else語句也可以達到較高的運行效率。

switch語句也有他本身的局限性,即switch語句的值只能為整型,比如當我們需要對一個double型數據進行判斷時,便無法使用switch語句,這時只能使用if……else語句來實現。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲欧美另类人妖| 日韩电影中文字幕一区| 国产欧美精品一区二区| 亚洲日本欧美中文幕| 欧美专区中文字幕| 欧美成人三级视频网站| 亚洲第一页自拍| 亚洲3p在线观看| 亚洲美腿欧美激情另类| 亚洲最新av在线网站| 欧美洲成人男女午夜视频| 91日韩在线播放| 欧美在线视频观看免费网站| 亚洲精品欧美一区二区三区| 欧美激情一区二区三区成人| 亚洲无限乱码一二三四麻| 亚洲精品国产suv| 情事1991在线| 国产精品日韩欧美综合| 亚洲xxxx18| 欧美性猛交xxxx免费看漫画| 久久久久久12| 亚洲国产精品专区久久| 成人情趣片在线观看免费| 国产www精品| 国产亚洲精品美女| 日韩视频免费大全中文字幕| 成人激情电影一区二区| 91精品视频大全| 成人免费午夜电影| 97热在线精品视频在线观看| 亚洲大胆人体av| 色综合天天狠天天透天天伊人| 在线播放精品一区二区三区| 久久视频国产精品免费视频在线| 97涩涩爰在线观看亚洲| 久久久亚洲成人| 国产精品久久久久9999| 一区二区三区视频免费在线观看| 久久av在线播放| 日韩国产精品亚洲а∨天堂免| 96精品久久久久中文字幕| 欧美综合在线观看| 亚洲欧美综合另类中字| 91av视频在线播放| 欧美精品在线第一页| 欧美天天综合色影久久精品| 日韩女优在线播放| 国产美女精品免费电影| 欧美成年人视频| 国语自产精品视频在线看抢先版图片| 精品亚洲一区二区三区在线观看| 欧美激情网站在线观看| 亚洲欧美福利视频| 久久久久久久久国产| 视频在线观看99| 一本色道久久综合狠狠躁篇怎么玩| 国产精品美女久久久久久免费| 8x海外华人永久免费日韩内陆视频| 精品无人区太爽高潮在线播放| 深夜福利日韩在线看| 在线观看久久av| 日本不卡高字幕在线2019| 国产日韩欧美在线观看| 久久久人成影片一区二区三区| 久久成人精品一区二区三区| 国产日韩中文字幕在线| 中文字幕最新精品| 久久九九免费视频| 国产精品成人v| 久久欧美在线电影| 日韩在线免费观看视频| 日韩欧美a级成人黄色| 国产精品白嫩美女在线观看| 日韩不卡中文字幕| 俺也去精品视频在线观看| 久久国产精品久久精品| 久久精品中文字幕| 777777777亚洲妇女| 欧美亚洲成人免费| 青青青国产精品一区二区| 亚洲国产精品美女| 国产欧美一区二区三区在线| 中文字幕av一区二区三区谷原希美| 国产日韩av在线| 成人激情视频在线观看| 日韩在线观看免费全| 久久69精品久久久久久国产越南| 日韩中文字幕第一页| 亚洲区中文字幕| 亚洲自拍欧美色图| 国产偷亚洲偷欧美偷精品| 性欧美暴力猛交69hd| 日韩综合视频在线观看| 欧洲亚洲妇女av| 成人午夜高潮视频| 中文国产亚洲喷潮| 久久久久久一区二区三区| 久久国产精品网站| 欧美精品少妇videofree| 欧美日韩一区二区三区| 欧美黑人一级爽快片淫片高清| 色琪琪综合男人的天堂aⅴ视频| 日韩女优在线播放| 精品国产乱码久久久久久天美| 久久久久久91香蕉国产| 欧美整片在线观看| 亚洲精品资源美女情侣酒店| 亚洲在线一区二区| 中文字幕成人在线| 久久精品福利视频| 国产精品久久久久久久久久ktv| 久久久久久国产精品| 在线看欧美日韩| 国产精品丝袜久久久久久不卡| 欧美性xxxx在线播放| 久久99久国产精品黄毛片入口| 亚洲福利视频网站| 国产不卡av在线免费观看| 精品亚洲aⅴ在线观看| 日韩免费观看高清| 国产999精品久久久| 在线观看视频亚洲| 久久久久一本一区二区青青蜜月| 国产精品三级网站| 国产精品久久久久久久av大片| 成人乱色短篇合集| 欧美亚洲在线视频| 国产成人极品视频| 亚洲免费电影在线观看| 日本aⅴ大伊香蕉精品视频| 亚洲综合国产精品| 91精品久久久久久久久久久久久久| 欧美大片欧美激情性色a∨久久| 亚洲色图25p| 欧美精品免费在线观看| 亚洲欧美中文字幕| 久久久精品久久久久| 国产亚洲日本欧美韩国| 九色精品美女在线| 亚洲精品免费在线视频| 欧美成aaa人片在线观看蜜臀| 国产精品777| 国产亚洲欧洲高清| 精品久久久香蕉免费精品视频| 亚洲视频在线视频| 国产精品激情av电影在线观看| 社区色欧美激情 | 中文字幕精品一区二区精品| 国产成+人+综合+亚洲欧美丁香花| 91高清视频在线免费观看| 亚洲精品第一国产综合精品| 国产精品久久久久aaaa九色| 疯狂蹂躏欧美一区二区精品| 亚洲高清福利视频| 亚洲精品99久久久久中文字幕| 色综合久久88色综合天天看泰| 国内精品久久久久久久| 中文字幕国产精品| 久久伊人91精品综合网站| 欧美国产亚洲视频| 久久久成人的性感天堂| 国产精品精品视频| 97婷婷涩涩精品一区|