第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

C#switch語句限制 - 為什么?

C#switch語句限制 - 為什么?

C#
富國滬深 2019-07-26 16:21:20
C#switch語句限制 - 為什么?在編寫switch語句時,在case語句中可以打開的內(nèi)容似乎存在兩個限制。例如(是的,我知道,如果你正在做這種事情,這可能意味著你的面向?qū)ο螅∣O)架構(gòu)是不確定的 - 這只是一個人為的例子!),  Type t = typeof(int);   switch (t) {     case typeof(int):       Console.WriteLine("int!");       break;     case typeof(string):       Console.WriteLine("string!");       break;     default:       Console.WriteLine("unknown!");       break;   }這里switch()語句失敗,帶有'一個預(yù)期的整數(shù)類型的值',case語句失敗并帶有'a expected value is expected'。為什么會有這些限制,以及基本理由是什么?我看不出有任何理由switch語句具有只能屈從于靜態(tài)分析,為什么在接通的值必須是完整的(即原語)。理由是什么?
查看完整描述

3 回答

?
冉冉說

TA貢獻1877條經(jīng)驗 獲得超1個贊

這是我的原帖,引發(fā)了一些爭論...... 因為它錯了

switch語句與if-else語句不同。每個案例必須是唯一的并且靜態(tài)評估。無論您有多少個案例,switch語句都會執(zhí)行一個恒定時間分支。if-else語句計算每個條件,直到找到一個為真。


實際上,C#switch語句并不總是一個恒定時間分支。

在某些情況下,編譯器將使用CIL開關(guān)語句,該語句確實是使用跳轉(zhuǎn)表的恒定時間分支。然而,在Ivan Hamilton指出的稀疏情況下,編譯器可能完全生成其他東西。

這實際上很容易通過編寫各種C#switch語句來驗證,一些稀疏,一些密集,并使用ildasm.exe工具查看生成的CIL。


查看完整回答
反對 回復(fù) 2019-07-26
?
慕桂英4014372

TA貢獻1871條經(jīng)驗 獲得超13個贊

重要的是不要將C#switch語句與CIL開關(guān)指令混淆。

CIL開關(guān)是一個跳轉(zhuǎn)表,需要索引到一組跳轉(zhuǎn)地址。

這僅在C#開關(guān)的情況相鄰時才有用:

case 3: blah; break;case 4: blah; break;case 5: blah; break;

但如果不是這樣的話,幾乎沒用:

case 10: blah; break;case 200: blah; break;case 3000: blah; break;

(你需要一個表~3000個條目,只使用3個插槽)

對于非相鄰表達式,編譯器可能會開始執(zhí)行線性if-else-if-else檢查。

對于較大的非相鄰表達式集,編譯器可以從二叉樹搜索開始,最后是if-else-if-else最后幾個項。

對于包含相鄰項塊的表達式集,編譯器可以進行二叉樹搜索,最后是CIL開關(guān)。

這充滿了“mays”和“mights”,它依賴于編譯器(可能與Mono或Rotor不同)。

我使用相鄰的案例在我的機器上復(fù)制了你的結(jié)果:

執(zhí)行10路開關(guān)的總時間,10000次迭代(ms):
每10路開關(guān)25.1383 近似時間(ms):0.00251383

執(zhí)行50路開關(guān)的總時間,10000次迭代(ms):
每50路開關(guān)的大約時間為26.593 (ms):0.0026593

執(zhí)行5000路開關(guān)的總時間,10000次迭代(ms):23.7094 
每5000路開關(guān)的近似時間(ms):0.00237094

執(zhí)行50000路開關(guān)的總時間,10000次迭代(ms):20.0933 
每50000路開關(guān)的近似時間(ms):0.00200933

然后我也使用了非相鄰的case表達式:

執(zhí)行10路開關(guān)的總時間,10000次迭代(ms):19.6189 
每10路開關(guān)的近似時間(ms):0.00196189

執(zhí)行500路開關(guān)的總時間,10000次迭代(ms):
每個500路開關(guān)的近似時間為19.1664 (ms):0.00191664

執(zhí)行5000路開關(guān)的總時間,10000次迭代(ms):
每5000路開關(guān)的大約時間為19.5871 (ms):0.00195871

不相鄰的50,000個案例切換語句將無法編譯。
“在'ConsoleApplication1.Program.Main(string [])'附近編譯表達式太長或太復(fù)雜

這里有趣的是,二叉樹搜索比CIL切換指令更快(可能不是統(tǒng)計上)。

Brian,你使用了“ 常量 ” 這個詞,從計算復(fù)雜性理論的角度來看,它具有非常明確的含義。雖然簡化的相鄰整數(shù)示例可以產(chǎn)生被認為是O(1)(常數(shù))的CIL,但稀疏示例是O(log n)(對數(shù)),聚類示例介于兩者之間,小例子是O(n)(線性) )。

這甚至不能解決Generic.Dictionary<string,int32>可能會創(chuàng)建靜態(tài)的String情況,并且在首次使用時會遇到明確的開銷。這里的表現(xiàn)將取決于表現(xiàn)Generic.Dictionary。

如果檢查C#語言規(guī)范(不是CIL規(guī)范),你會發(fā)現(xiàn)“15.7.2 switch語句”沒有提到“常量時間”或底層實現(xiàn)甚至使用CIL開關(guān)指令(要非常小心假設(shè)這樣的事情)。

在一天結(jié)束時,針對現(xiàn)代系統(tǒng)上的整數(shù)表達式的C#切換是亞微秒操作,通常不值得擔(dān)心。


當(dāng)然,這些時間將取決于機器和條件。我不會注意這些時序測試,我們所討論的微秒持續(xù)時間與正在運行的任何“真實”代碼相比相形見絀(并且您必須包含一些“真實代碼”,否則編譯器將優(yōu)化分支),或者系統(tǒng)中的抖動。我的答案基于使用IL DASM來檢查C#編譯器創(chuàng)建的CIL。當(dāng)然,這不是最終的,因為CPU運行的實際指令隨后由JIT創(chuàng)建。

我檢查了在我的x86機器上實際執(zhí)行的最終CPU指令,并且可以確認一個簡單的相鄰設(shè)置開關(guān),例如:

  jmp     ds:300025F0[eax*4]

二叉樹搜索滿滿的地方:

  cmp     ebx, 79Eh
  jg      3000352B
  cmp     ebx, 654h
  jg      300032BB
  …
  cmp     ebx, 0F82h
  jz      30005EEE


查看完整回答
反對 回復(fù) 2019-07-26
  • 3 回答
  • 0 關(guān)注
  • 757 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號