[英]How does switch compile in Visual C++ and how optimized and fast is it?
當我發現我只能在C ++的switch
語句中使用數值時,我認為它必須在它和一堆if-else
之間有一些更深的區別。
所以我問自己:
switch
與if-elseif-elseif
區別是什么? 我這里主要談的是MSVC。 通常將開關編譯為跳轉表(一個比較以找出要運行的代碼),或者如果不可能,則編譯器仍然可以對比較進行重新排序,以便在值之間執行二進制搜索(log N)比較)。 if-else鏈是一個線性搜索(雖然,我想,如果所有相關值都是編譯時積分常數,編譯器原則上可以執行類似的優化)。
Switch語句通常是編譯器優化的常見來源。 也就是說,它們的處理方式取決於您在編譯器上使用的優化設置。
編譯switch語句的最基本(未優化)方法是將其視為if ... else if ...
語句的鏈。 編譯器優化開關的常用方法是將其轉換為跳轉表 ,其類似於:
if (condition1) goto label1;
if (condition2) goto label2;
if (condition3) goto label3;
else goto default;
label1:
<<<code from first `case statement`>>>
goto end;
label2:
<<<code from first `case statement`>>>
goto end;
label3:
<<<code from first `case statement`>>>
goto end;
default:
<<<code from `default` case>>>
goto end;
end:
這種方法更快的一個原因是因為條件中的代碼較小(因此如果條件被錯誤預測,則會有較小的指令緩存懲罰)。 此外,“落空”案例變得更加簡單(編譯器不使用goto end
語句)。
編譯器可以通過創建指針數組(到標簽標記的位置)來進一步優化跳轉表,並使用您要切換的值作為該數組的索引。 這將消除代碼中的幾乎所有條件(除了驗證您正在接通的值是否與您的一個案例匹配所需的任何條件除外)。
需要注意的是:嵌套跳轉表很難生成,有些編譯器甚至拒絕嘗試創建跳轉表。 出於這個原因,避免嵌套一個switch
另一個內部switch
,如果最大限度地優化代碼,重要的是你(我不知道100%MSVC特別程序如何處理嵌套switch
ES,但是編譯器手冊應該告訴你)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.