在C#下有什麼好辦法可以替代if-else和switch-case?
我準備研究研究用C#寫一個音樂腳本解析器,解析用戶的腳本並按需放出制定聲音,從而生成能聽的曲子。如果解析用戶的腳本用了大量switch-case和if-else判斷文本,據說會導致效率變得很差,整個程序可能會變慢影響輸出的曲子節奏,從而帶來不必要的延遲影響體驗。這種情況該怎麼解決?
不是因為「用戶編寫的腳本里的if-else」導致的問題嗎?為什麼你會覺得「C#編寫的解析器」里的if-else慢?再怎麼說也應該是「C#編寫的解析器」里處理「用戶腳本的if-else」的方式慢么。
還有,Profiling,Profiling,Profiling。一切性能問題,必須以Profiling的結論為準。
我基本上可以斷定你的性能問題不在於if ... else或是switch ... case。
據說的可信度,尤其是性能問題的據說可信度基本接近於零。
如果要把一個解析器寫的像shit一樣,大量不知所云的if ... else或者switch ... case或許是不可或缺的。但是這並不代表這些東西性能差,只是像shit一樣的代碼中出現的一些共性罷了。看了一下回答,有點懷疑到底有多少答主有實際項目經驗。有質疑精神固然是好,但沒有解決題主的困惑啊。只有 毛草 同學提到了可行的方案。
這種情況做預處理就行了,就是把腳本預先處理成對性能要求不高中間格式,至於這個格式是什麼樣子就要題主自己去琢磨了。然後播放的時候用中間格式解析。看看是不是if判斷裡面反覆調用了一個函數~
笑尿,建議你每一個if-else之前把時間戳log出來,然後看哪個慢了,對於普通人來說,就算你寫一萬個if-else ,估計也不會覺得延遲,因為是條件遍歷,除非你的遍歷條件是一個方法,坑人不算,還坑的一手好計算機,這等黑科技,什麼方法都挽救不了你
if else只會亂,不會慢。
你覺得計算機判斷if else這種語句會成為性能瓶頸?
if/else和switch/case本身不會對性能有太多影響,除非你用的實在太多
如果要避免這種判斷的話,最好的辦法是在執行前直接生成決策樹,然後直接調用,而不是在執行時通過條件臨時判斷。
可以考慮的方法有預處理,SOLID中的L,還有上邊說的通過HashTable調用預先做好的流程。
但是實際上,大多數情況下,if/else和case/switch基本都不可能是你的瓶頸所在吧
性能影響原因應該不是這個,如果非要換,弄個數組去索引是最快的
too naive,你寫1億個switch再來說性能瓶頸吧
Dictionary + lambda
但是對於這種託管的語言,我覺得if else或者switch都不會是瓶頸的,因為你編譯得到的不是最終執行的代碼,虛擬機還可以運行時優化有沒有呢,當然有,那就是索引,index,HashTable。
由於用戶腳本生成的MIDI是由特定音符組成的,那麼我們假定我們支持的輸出聲音分為音色,音高和響度三個維度。我們首先需要建立一個支持這三個維度的大型Dictionary。為了簡化這個問題,我們假設支持3種音色、音高、響度。那麼建立的的對象就為var midiDic = new Dictionary&var midi = midiDic[0][0][0];
直接訪問我們支持的第一種音色,第一種音高和第一種響度。Midi是你自己寫的一個類,這個類有基本的功能,這個功能就是發出聲音。midi.OutLoudAdiou(soundTime);由於索引的速度要高於遍歷,所以可以一定程度上的解決問題,缺點是Dictionary是佔用內存空間的,越複雜的Dictionary越佔用空間。
那麼我們可以使用動態載入。比如鋼琴的midi,小提琴的midi,交響樂的midi,載入的dictionary大小並不相同,但是分時載入,按腳本頭載入都是可以成為可能的。單樂器控制載入數量,多樂器控制調用偏移量即可。
由於音樂的特殊性,可能同時存在兩個聲音同時響起,這種情況建議使用多線程,並注意控制時間。線程的切換是μs級別,人是不可能聽出來的,因為鬼父神功(大霧)的交響樂團也做不到完全的同時發聲。記得以前老師說過有一些編程語言是沒有if else 的。 可以利用polymorphism 解決。 這樣: note 作為父類並有一method 叫play。 每個音符如a,b,c… , 都繼承note 並各實現不同的play 。 播放的時候,循環曲目中的note 列,只要都call play 就可以不用if else了。當然interface 也是可以的。更多請看wiki。 https://en.m.wikipedia.org/wiki/Polymorphism_(computer_science)
不想用switch case可以查表啊。。。
而且,你增加減少個項目不用改動代碼一分一毫!老流弊了!!老優雅了!!!
但是,查錶帶來的優雅的寫法的代價是性能降低啊!騷年,你要記住這麼一個真理:
在等效並且沒有做無意義的額外操作的前提下,代碼越醜陋,效率就越高!
沒啥好辦法,我有更壞的方法,用goto
多態 + 模式
比如 你用工廠方法或者各種di框架注入一個實例 你就能很好地避免一堆if else了為啥會慢呢?人家compiler可比大多數碼農聰明。
通過合理的繼承關係可以減少很多條件判斷語句,而且效率那麼低多半並不是條件判斷本身的問題,可能你還沒有找到根源。
我不回答題主問題。
說虛表、字典、哈希表的,你們真的覺得這些比比if/switch快?還是在現代CPU的情況下?
題主還不到擔心這個性能的時候吧。c#有這麼多腳本語言可用,何必自己造輪子?
真有必要,換c++寫模板吧。把可以在編譯期搞掉的if在編譯期搞掉。推薦閱讀:
※如何利用 Matlab實現矩陣相同元素的查找?
※如何能專心的下來打代碼?
※有哪些適合matlab初學者編寫、同時簡單實用的結構分析小程序?
TAG:微軟Microsoft | MIDI | 編程 | 計算機 | C# |