精准提升项目性能-代码优化必备技巧
本文将项目中常用的代码技巧进行汇总,这些不仅仅是大麦项目中应用,而且是所有的项目都会用到的技巧,正所谓 看万卷书不如行万里路 ,里面会有你在书上看见的技巧,接下来看看真正的实践应用到底是什么样子
用return减少if分支的数量
可以用return直接将符合条件的结果进行返回
假设我们有一个方法,根据传入的数字返回对应的字符串描述
用常规的if分支来实现
java
public String describeNumber(int number) {
String description = "";
if (number == 1) {
description = "One";
} else if (number == 2) {
description = "Two";
} else if (number == 3) {
description = "Three";
} else if (number == 4) {
description = "Four";
} else {
description = "Unknown number";
}
return description;
}用return进行优化实现
我们可以通过在每个if条件满足时立即返回结果,从而减少if分支的数量。这样做的好处是,一旦找到匹配的条件,方法就会立即返回,不会继续检查后面的条件
java
public String describeNumberOptimized(int number) {
if (number == 1) {
return "One";
}
if (number == 2) {
return "Two";
}
if (number == 3) {
return "Three";
}
if (number == 4) {
return "Four";
}
return "Unknown number";
}遇到业务逻辑异常情况直接使用return提前结束
在大麦项目中的 **节目详情中预先加载购票人列表 **业务中就是利用此技巧进行优化的,我们先来看下不使用return,而是常规的if分支的实现
用常规的if分支来实现
java
/***
* 预先加载用户下的购票人
*/
private void preloadTicketUserList(Integer highHeat){
if (Objects.equals(highHeat, BusinessStatus.YES.getCode())) {
String userId = BaseParameterHolder.getParameter(USER_ID);
String code = BaseParameterHolder.getParameter(CODE);
if (StringUtil.isNotEmpty(userId) && StringUtil.isNotEmpty(code)) {
BusinessThreadPool.execute(() -> {
try {
Boolean userLogin = redisCache.hasKey(RedisKeyBuild.createRedisKey(RedisKeyManage.USER_LOGIN, code, userId));
if (userLogin) {
if (!redisCache.hasKey(RedisKeyBuild.createRedisKey(RedisKeyManage.TICKET_USER_LIST,userId))) {
TicketUserListDto ticketUserListDto = new TicketUserListDto();
ticketUserListDto.setUserId(Long.parseLong(userId));
ApiResponse<List<TicketUserVo>> apiResponse = userClient.select(ticketUserListDto);
if (Objects.equals(apiResponse.getCode(), BaseCode.SUCCESS.getCode())) {
Optional.ofNullable(apiResponse.getData()).filter(CollectionUtil::isNotEmpty)
.ifPresent(ticketUserVoList -> redisCache.set(RedisKeyBuild.createRedisKey(
RedisKeyManage.TICKET_USER_LIST,userId),ticketUserVoList));
}else {
log.warn("userClient.select 调用失败 apiResponse : {}",JSON.toJSONString(apiResponse));
}
}
}
}catch (Exception e) {
log.error("预热加载投票人列表失败",e);
}
});
}
}
}可以看到不优化的话,代码看起来也不够简洁干练,if的分支非常的多,最多已经达到了5层if分支,如果不适用Optional的ifPresent方法的话,就会达到6层if分支
当if分支过多时,会有以下坏处:
- 可读性和可维护性下降:过多的if分支使得代码变得复杂且难以阅读。其他开发者或未来的你可能难以理解每个分支的逻辑和目的。此外,当需要修改或添加新的分支时,维护成本会增加
- 性能问题:虽然现代编译器和处理器优化了许多这样的问题,但过多的if分支可能会导致性能下降。每次执行到if语句时,都需要进行条件判断,这会增加CPU的负载。尤其是在嵌套if的情况下,性能问题可能更加严重
- 错误风险增加:随着if分支数量的增加,出错的可能性也会增加。例如,可能会不小心遗漏某个分支,或者在不同的分支中重复了相同的代码逻辑
- 扩展性差:当业务逻辑发生变化,需要添加或删除分支时,过多的if分支会使代码变得难以修改。这可能导致需要重构整个方法或类,增加了开发时间和成本
- 不利于使用设计模式:设计模式是解决特定问题的一种优秀方案。但是,过多的if分支可能会使代码结构变得僵化,不利于应用设计模式来简化或优化代码
在阿里巴巴开发规范手册中建议了,方法中的if嵌套最多不要超过3层。在实际开发中也确实建议大家这样做,当if分支过多后,就会有很多想不到的漏洞出现,本人之前也是踩着这些坑过来的
那么现在来看看如何使用return来减少if分支的嵌套数量
用return进行优化实现
java
/***
* 预先加载用户下的购票人
*/
private void preloadTicketUserList(Integer highHeat){
//如果节目是热度不高的,那么不用预先加载了
if (Objects.equals(highHeat, BusinessStatus.NO.getCode())) {
return;
}
String userId = BaseParameterHolder.getParameter(USER_ID);
String code = BaseParameterHolder.getParameter(CODE);
//如果用户id或者code有一个为空,那么判断不了用户登录状态,也不用预先加载了
if (StringUtil.isEmpty(userId) || StringUtil.isEmpty(code)) {
return;
}
//异步加载购票人信息,别耽误查询节目详情的主线程
BusinessThreadPool.execute(() -> {
try {
Boolean userLogin = redisCache.hasKey(RedisKeyBuild.createRedisKey(RedisKeyManage.USER_LOGIN, code, userId));
//如果用户没有登录,也不用预先加载了
if (!userLogin) {
return;
}
//如果已经预热加载了,就不用再执行了
if (redisCache.hasKey(RedisKeyBuild.createRedisKey(RedisKeyManage.TICKET_USER_LIST,userId))) {
return;
}
TicketUserListDto ticketUserListDto = new TicketUserListDto();
ticketUserListDto.setUserId(Long.parseLong(userId));
ApiResponse<List<TicketUserVo>> apiResponse = userClient.select(ticketUserListDto);
if (Objects.equals(apiResponse.getCode(), BaseCode.SUCCESS.getCode())) {
Optional.ofNullable(apiResponse.getData()).filter(CollectionUtil::isNotEmpty)
.ifPresent(ticketUserVoList -> redisCache.set(RedisKeyBuild.createRedisKey(
RedisKeyManage.TICKET_USER_LIST,userId),ticketUserVoList));
}else {
log.warn("userClient.select 调用失败 apiResponse : {}",JSON.toJSONString(apiResponse));
}
}catch (Exception e) {
log.error("预热加载投票人列表失败",e);
}
});
}在此方法中,**当判断的条件不符合业务要求时,直接使用return将流程提前结束。每用一次return就会将一种异常情况进行结束,**如果执行的流程都没有被return终止掉,就说明是符合业务逻辑的,直接执行业务就可以了
更新: 2025-10-13 12:02:08
原文: https://www.yuque.com/u22210564/ykdrdh/yaycsk2iognptm3z