Skip to content

精准提升项目性能-代码优化必备技巧

本文将项目中常用的代码技巧进行汇总,这些不仅仅是大麦项目中应用,而且是所有的项目都会用到的技巧,正所谓 看万卷书不如行万里路 ,里面会有你在书上看见的技巧,接下来看看真正的实践应用到底是什么样子

用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

Java 后端面试知识库