Java 求解如何优化 100 个 if 判断?

2022-11-07 21:04:51 +08:00
 whereisgungun
需求是这样的:
上游服务调用接口( TCP 协议,用 netty 做了服务端,上游是客户端)发来报文,这个报文里面会有 35 个属性,我们简单定义这 35 个属性为 A 、B 、C 、D....然后每个属性的值为 a 、b 、c 、d....现在有接近 100 个模板,然后我们的功能就是要根据报文来确定要用哪一个,重点是这 100 个模板是没有规律的。

比如:
if(a==1 && b==2) {return "模板 1";}
if(c.length==1 && d.equals("xxx")) {return "模板 2";}
...
也就是说,会有 100 个 if 判断来确定此次调用的报文对应哪个模板,而且报文是不冲突的,35 个属性的值只要命中其中一个模板,其他的就都不符合,都是互斥的。(算是 CompletableFuture 的 anyOf 方法。)

现在暂时找不出这 100 个 if 里面有什么具体的规律,35 个属性也没有。求问各位大神有什么好的思路优化吗?线程池 or 中间件?

PS:作为最底层的外包,也没法要求上游能做什么改动了。。他们是一个老旧的银行系统,以前也是用的一个一个判断来着,现在把项目丢给我们了。。
7391 次点击
所在节点    程序员
82 条回复
NeroKamin
2022-11-08 10:06:20 +08:00
可以优化代码,但是对于性能上优化可能不太会有帮助
mingsz
2022-11-08 10:43:02 +08:00
不动,继续加 if
万一重构后,部分逻辑与之前不一样就 gg
6david9
2022-11-08 10:47:41 +08:00
看下响应链模式是否满足你的需求
fgwmlhdkkkw
2022-11-08 10:52:14 +08:00
每个模板需要的参数和值是确定的,那就可以查表呀。

"a:a1,b:b1..." : tpl1
"a:a2,b:b1..." : tpl2
leonshaw
2022-11-08 10:55:05 +08:00
判断这块需要优化的依据是什么?
MYli001
2022-11-08 10:57:11 +08:00
放 map 里面最简单
fgwmlhdkkkw
2022-11-08 10:57:25 +08:00
@fgwmlhdkkkw #44
如果值不是确定的,那可以 `({fn: (params: Params) => bool, hits: number})[]`依次执行,找到 hits 加一,一段时间后按照 hits 降序,理论上也会提高性能。
fgwmlhdkkkw
2022-11-08 10:58:20 +08:00
但是你要让我改,我肯定不想改……
kingbill
2022-11-08 11:10:55 +08:00
提升性能的话,是打算并发判断吗?好像也不是不行,但总感觉没有必要
jsjjdzg
2022-11-08 11:13:23 +08:00
各种规则引擎下来还是 if 最快,把常用的 if 条件放前面就是最好的
HugoChao
2022-11-08 11:20:33 +08:00
才一百个,没有性能问题吧。保持这个结构,方便以后继续改逻辑
7911364440
2022-11-08 11:36:19 +08:00
txy3000
2022-11-08 11:39:06 +08:00
做个 profile 再来谈性能 你确定瓶颈是 if 太多?
shanghai1943
2022-11-08 11:57:45 +08:00
假如你为了所谓的命中率高的放前面,移动了 if 的逻辑判断顺序,会不会导致某些业务逻辑的执行顺序发生变化了。

假设存在两种传参 a=1,b=2 和 a=1,b=2,c=3 ,以及两种 if 判断 a=1&&b=2 和 a=1&&c=3 ,如果调整了 if 的判断顺序,可能执行的业务就变得不一样了。

建议慎重。。
HanMeiM
2022-11-08 12:24:13 +08:00
用 map 做 key -> function 的驱动注册
hhjswf
2022-11-08 12:27:04 +08:00
if else 能有什么性能问题无非是丑了点
cyrbuzz
2022-11-08 12:53:26 +08:00
每个判断写成一个函数?对应的返回值可以写成枚举,1,2,3,4 这样,然后枚举和模板对应起来。

js 代码:

```
const enmu = {
1: '模板 1',
....
}

const judgeFunc = [() => { return false }, () => { return true }]


const finded = judgeFunc.findIndex((func) => { return func() })

// 加判断
enmu[finded]()
```

随便扩展 enmu 和 judgeFunc 就可以了。
bk201
2022-11-08 13:05:17 +08:00
优化的目的是啥?增强可读性还是要做扩展?老系统能用就不要优化。你要优化,那还是那句话,首先优化的目标是啥?
Ashore
2022-11-08 13:12:25 +08:00
改出问题你负责?不要想着去优化这个优化那个,业务能跑才是最重要的。
vacuitym
2022-11-08 13:16:11 +08:00
如果是为了程序可读性,而且每个变量对应的判断只有一种,可以对每个变量做一次真假的判断,然后存到一个 100 位的二进制中,然后对 100 个模版进行二进制的对应

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/893424

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX