Soft_Job 板


LINE

※ 引述《unixxxx (皓皓)》之銘言: : 標題: Re: [討論] 寫三元判斷式code review被打槍 : 時間: Sat Dec 17 03:51:38 2022 : 很多Javascript 高手都是用 switch 取代 "特定"情況下的確是好方式 舉個例子 以前我在調校能時候有用過這種方式 這是c#的code部分節錄 void Mem_w(ushort address, byte value) { if (address < 0x2000) NES_MEM[address & 0x7ff] = value; else if (address < 0x4020) IO_write(address, value); else if (address < 0x6000) MapperRouterW_ExpansionROM(address,value); else if (address < 0x8000) MapperRouterW_RAM(address, value); else MapperRouterW_PRG(address, value); } 這個是一個非常頻繁被呼叫的method 如果address 大於等於0x8000 其實前面就浪費好幾次計算在判斷式上 因此改成 功能上是相等的 static void Mem_w(ushort address, byte value) { switch (address & 0xf000) { case 0: case 0x1000: NES_MEM[address & 0x7ff] = value; break; case 0x2000: case 0x3000: case 0x4000: IO_write(address, value); break; case 0x5000: MapperObj.MapperW_ExpansionROM(address, value); break; case 0x6000: case 0x7000: MapperObj.MapperW_RAM(address, value); break; case 0x8000: case 0x9000: case 0xa000: case 0xb000: case 0xc000: case 0xd000: case 0xe000: case 0xf000: MapperObj.MapperW_PRG(address, value); break; } } 但再簡化快速下去還有大招 初始化執行一次就好 static void init_function() { mem_write_fun = new Action<ushort, byte>[0x10000]; for (int address = 0; address < 0x10000; address++) { if (address < 0x2000) mem_write_fun[address] = new Action<ushort, byte>((addr, val) => { NES_MEM[addr & 0x7ff] = val; }); else if (address < 0x4020) mem_write_fun[address] = new Action<ushort,byte>(IO_write); else if (address < 0x6000) mem_write_fun[address] = new Action<ushort, byte>(MapperObj.MapperW_ExpansionROM); else if (address < 0x8000) mem_write_fun[address] = new Action<ushort, byte>(MapperObj.MapperW_RAM); else mem_write_fun[address] = new Action<ushort, byte>(MapperObj.MapperW_PRG); } } 之後讀取 [MethodImpl(MethodImplOptions.AggressiveInlining)] static void Mem_w(ushort address, byte value) { mem_write_fun[address](address, value); } 實際上跟switch原理很相似 但直接把mapper的實作 哪個address對應啥動作 直接寫到記憶址array去了 我是不知道你所謂的javascript高手用switch替代判斷式是碰到啥議題 但特定議題用改用switch 甚至自己刻死路由效能是會快非常多 以前有筆記在這邊... https://dotblogs.com.tw/enet/2017/01/21/emu_optimization_1 --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 39.15.64.117 (臺灣)
※ 文章網址: https://webptt.com/m.aspx?n=bbs/Soft_Job/M.1672067047.A.133.html ※ 編輯: erspicu (39.15.64.117 臺灣), 12/26/2022 23:04:55 ※ 編輯: erspicu (39.15.64.117 臺灣), 12/26/2022 23:13:24
1F:→ MoonCode: ... 12/26 23:47
2F:→ MoonCode: 快不快還是 benchmark 或看編譯出來什麼東西吧 12/26 23:48
有用FPS測過 提升很大 看到前面有人推文提到 ARRAY LOOKUP最快 其實就是這種方式 ※ 編輯: erspicu (39.15.64.117 臺灣), 12/26/2022 23:52:39
3F:推 MoonCode: 12/27 00:01
4F:推 jason222333: 推 12/27 06:32
5F:推 DarkIllusion: 好奇問 為什麼這裡switch-case會比多重if-else快? 12/27 06:48
6F:→ DarkIllusion: 以及 為什麼這裡用function map比switch-case快? 12/27 06:50
7F:推 DarkIllusion: 如果頻繁判斷address大於等於0x8000 那這判斷放前面 12/27 06:55
沒人知道 ADDRESS到底是落在哪個區間多 這就問題
8F:→ DarkIllusion: 為什麼不會是個好的解法? 12/27 06:56
9F:推 Jichang: 這不是大一計概就會教的 if else 是循序判斷 switch 是ju 12/27 06:58
10F:→ Jichang: mp map是hash 但是好的compiler可以直接最佳化if else 12/27 06:58
11F:推 DarkIllusion: 抱歉 我比較沒有計概常識 12/27 07:01
最終結果其實是多重因素下複合產生的 所以與其問為什麼 最快其實就是跑看看才準 當然要從理論層出發談談也不是不行 但談理論有時候實際就會是出乎意料 至於 if else -> switch -> array lookup case多時候為啥比較快 循序判斷本身就是計算成本 至於switch跟array lookup其實精神上是類似做法 就一個查表動作 不過還是得實際測一下 有時候這也跟實際case有關係 就所處電腦硬體條件 如果RAM慢到一個程度 慢到一次查表 乾脆讓CPU去完成幾次計算 還比一次查表快 那就用if else 後來發現一切理論都沒那麼可靠 要考量的太多 實測就知道答案 而且實測的答案 說不定在不同硬體條件下又是別的狀況 C#會輸出IL CODE看IL CODE也不太準 看JIT編譯出的東西才知道真正做啥事情 知道真正做啥事情 有時候也要考慮到硬體差異 查表法說白了就是先將答案算出來記錄下來 直接查 是存取記憶體ARRAY的COST 計算量大時候 先算計下來會比較快 但如果記憶體存取的COST高於重算幾次的CPU計算 那乾脆就重算一次.... 這些都不是非常一定 直接測一測是最好的方式 剩下都紙上談兵 意料之外的結果會常常發生
12F:→ DarkIllusion: 看來原PO用的是沒那麼好的compiler :( 12/27 07:07
微軟在C#輸出的優化應該已經是標竿了 ※ 編輯: erspicu (39.15.64.117 臺灣), 12/27/2022 12:48:33
13F:→ leolarrel: 單純補充一下,這應該不適合在C. 剛用gcc 看組語內容, 12/27 13:44
14F:→ leolarrel: switch 仍然用比較且跳躍來實作 12/27 13:44
其實就像前面說的 真的都要實際跑看看才準或是看到ASM層去才比較有意義 沒有一定的萬用通則
15F:推 MyNion: 你下面陣列開了六萬多個再用for去跑,真的需要那麼多個? 12/27 15:54
16F:→ MyNion: 因為你的case只有五種,要不要數字進來都/5,這樣較省空間 12/27 15:56
※ 編輯: erspicu (39.15.64.117 臺灣), 12/27/2022 19:48:40
17F:推 chuegou: 就算是C 還可以問你優化編譯有沒有開 12/27 22:08
18F:→ peter98: 這種其實沒甚麼好討論的 就算真的這樣做有用 也只是單 12/27 22:35
19F:→ peter98: 一case適用 另外 profiling的情況是有規定的 不是隨便 12/27 22:35
20F:→ peter98: 跑 上次不知道哪個人開debug mode做profiling 原本想說 12/27 22:36
21F:→ peter98: 甚麼 後來想想還是算了 12/27 22:36
22F:→ peter98: 打錯 我是指開IDE去run程式做profiling 12/27 22:38
23F:推 wulouise: 開IDE跟profiling是之間沒有關係,除非開debug build 12/28 12:27
24F:→ leolarrel: chuegou, 我用gcc -O0跟-O3測試.你也可以自己試試看 12/28 13:19
25F:推 ku399999: 好奇效能差很多最後是快多少 func功能還是比條件判斷 12/30 09:37
26F:→ ku399999: 佔更多執行時間才對 12/30 09:38







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Gossiping站內搜尋

TOP