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 --
QR Code



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 39.15.64.117 (台湾)
※ 文章网址: https://webptt.com/cn.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灯, 水草

请输入看板名称,例如:WOW站内搜寻

TOP