各位 v 友,帮忙看看这个思路对不对
项目里面有个函数调用频率很高(极高), 大概长这样,
char *cmd=input //string,输入
if (cmd == "cmd1")
dosomething1
else if cmd== “cmd2”
dosomething2
这里 cmd1 cmd2 是举例的常数,实际是 30 位以内的字符串
if 大概有 200 多个分支,( 就是你们批判的那种,一个 if 几百分支,我接下了) 我想优化下, 目前有两个想法,望各位指正
思路 1: 统计每个 cmd 使用频率,调整 if 顺序,高频在前,低频在后,这样优化估计(目测)有些作用。(这主要是作为思路 2 被卡住了的备选
思路 2,把 string 快速转换成 int,利用 switch case 跳转,这样当然是最好的(吗?),初步想法是 把 sting 各位按不同权重求和得到 int,这个做成一个宏,这样,即使冲突了,编译器会报错。 最终代码是这样,
int cmdn = sum ( cmd )//这个是输入,运行时计算
switch cmdn:
case M(CMD1)://M 是宏,返回一个常数
DO SOMETHING
case M(cmd2 ):
do something 2
这样,新加 cmd3 命令 即使求权重和前面冲突了,编译器会立即报错,我只需要修改字符串某几位权重或者换个命令名就行。
关键点来了,如何写这个宏呢?
要优雅,不要污,最好是接受一个参数
不要这样
M ( c,m,d,1 )
要这样
M(cmd)
ps:我其实有点怀疑宏能不能做到这个 (分割字符串)
1
ysc3839 2021-10-09 06:48:54 +08:00 via Android 1
宏大概做不到,不过 C++的 constexpr+std::integral_constant 可以实现编译期计算。
具体可以参考我写的 i18n 库,里面用到了 FNV Hash 。 https://github.com/ysc3839/yi18n/blob/7165a74a31d8bb65983066e908d07b4d50694299/I18n.hpp#L62 |
2
wxd92 2021-10-09 06:59:26 +08:00 via iPhone
试下 map 呢?
cmdMap[“cmd”] = dosomething |
3
wd 2021-10-09 07:00:36 +08:00 via iPhone
如果是 python 的话,我会做一个 map,key 是 cmd value 是个 function,然后就是 map 里面 get 下 cmd key 执行就可以了
|
4
xuanbg 2021-10-09 07:03:31 +08:00
哈希表呀! cmd 字符串作为 key,123 作为 value 不就好啦。
|
5
liuidetmks OP |
6
angryfish 2021-10-09 08:50:24 +08:00 5
个人觉得根本没必要优化,有同意我观点的人儿吗?
|
7
xuanbg 2021-10-09 08:50:34 +08:00
@liuidetmks 哈希表可不是红黑树,查询时间复杂度是 O(1)
|
8
ysc3839 2021-10-09 09:00:25 +08:00 via Android
@liuidetmks C++有基于 hash 的 unordered_map,不过这个和 switch 比哪个快可能要测试了才知道。
|
9
notyss 2021-10-09 09:08:02 +08:00
benchmark it!
|
10
dwlovelife 2021-10-09 09:47:53 +08:00 1
这样优化是为了提高一点人都感觉不到的效率么,为啥子不是想着优化复用性呢。
|
11
liuidetmks OP |
12
bfdh 2021-10-09 10:30:55 +08:00
单纯 if 改 switch 是没有效果的,switch 和 if 对于常量的比较逻辑是一样的。
|
13
dirtysalt 2021-10-09 10:56:33 +08:00
要不要先找找每个字符串的特点,看看能不能快速映射成为 int
如果 swtich 里面的范围是连续的话,那么编译器会会生成表格跳转的,效果也非常好 https://dirtysalt.github.io/html/c-switch-table-in-asm.html 如果字符串已知的话,那么就可以手工地设计一个映射函数,比如 cmd1->0, cmd2->1 这样 |
14
CEBBCAT 2021-10-09 11:05:00 +08:00
赞同楼上的函数 map,优点如下:
1. 防命令冲突 2. 跳转逻辑重定位到了 map,跳转函数代码可以缩短到数行,逻辑清晰 至于性能这方面……我想也许可以做个 benchmark,也许就只是几纳秒的事 |
15
Nich0la5 2021-10-09 11:46:01 +08:00
hashMap<string,func>
|