You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Java枚举switch首次执行比if等价实现慢得多?

为何Java的枚举switch首次执行比等价的if实现慢得多?

我了解JVM需要进行“warm-up”后才能可靠地测量性能,因此首次调用比后续调用慢得多,但这并不意味着我们无法基于首次执行来测量性能。

测试标准

  • 始终执行全新运行。
  • 以nanoseconds为单位测量单个函数的执行时间,该函数根据传入值通过if语句或switch语句返回整数。
  • 存储返回值并在最后打印,避免其被优化丢弃。

测试结果

枚举测试

  • 77596 nanoseconds - if实现
  • 585232 nanoseconds - switch实现

为确认是否仅枚举存在该问题,我还测试了整数和字符串(Java 7起支持字符串switch):

整数测试:

  • 2308 nanoseconds - if实现
  • 1950 nanoseconds - switch实现

字符串测试:

  • 8517 nanoseconds - if实现
  • 8322 nanoseconds - switch实现

这两项测试结果相近,表明if与switch语句在各次运行中性能相当,但枚举的情况并非如此。我在Windows、Linux平台,Java 8和Java 17版本下均进行了测试。

测试代码

枚举switch实现代码

public class SwitchEnum{
    public static void main(String[] args){
        long st = System.nanoTime();
        int val = getValue(Day.FRIDAY);
        long en = System.nanoTime();
        System.out.println("SwitchEnum perf nano: " + (en - st));
        System.out.println("Sum: " + val);
    }

    public static int getValue(Day day){
        switch (day){
            case MONDAY:
                return 7;
            case TUESDAY:
                return 3;
            case WEDNESDAY:
                return 5;
            case THURSDAY:
                return 2;
            case FRIDAY:
                return 1;
            case SATURDAY:
                return 6;
            case SUNDAY:
                return 4;
            default:
                throw new RuntimeException();
        }
    }
}

枚举if实现代码

public class IfEnum{
    public static void main(String[] args){
        long st = System.nanoTime();
        int val = getValue(Day.FRIDAY);
        long en = System.nanoTime();
        System.out.println("IfEnum perf nano: " + (en - st));
        System.out.println("Sum: " + val);
    }

    public static int getValue(Day day){
        if (day == Day.MONDAY){
            return 7;
        }else if (day == Day.TUESDAY){
            return 3;
        }else if (day == Day.WEDNESDAY){
            return 5;
        }else if (day == Day.THURSDAY){
            return 2;
        }else if (day == Day.FRIDAY){
            return 1;
        }else if (day == Day.SATURDAY){
            return 6;
        }else if (day == Day.SUNDAY){
            return 4;
        }else{
            throw new RuntimeException();
        }
    }
}

枚举Day定义

public enum Day{
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

补充说明与疑问

我也在C和C#中测试了枚举switch与if的性能,未发现显著差异。同时注意到添加default或else分支可提升性能,因此所有测试均包含该分支。

本问题并非讨论常规的“if vs switch”性能对比,而是聚焦枚举与switch语句组合的异常表现。为何枚举switch的首次执行平均比等价if慢7倍?其性能开销的来源是什么?

似乎我被误解了,最初的枚举完全不同,为找到“不合理开销”的根源,我设计了此基准测试。有趣的是,预热JVM对该函数的性能毫无帮助。即使在目标方法前添加嵌套循环:

添加预热逻辑后的测试代码

public static void main(String[] args) throws InterruptedException{
        for (int i = 0; i < 1000; i++){
            for (int j = 0; j < 1000; j++){
                System.out.println(j);
            }
            System.out.println(i);
        }
        Thread.sleep(100);
        for (int i = 0; i < 1000; i++){
            System.out.println(i);
        }
        long st = System.nanoTime();
        int val = getValue(Day.FRIDAY);
        long en = System.nanoTime();
        System.out.println("SwitchEnum perf nano: " + (en - st));
        System.out.println("Sum: " + val);
    }

唯一影响性能的是该方法是否已被调用过,后续调用都会被优化。例如框架初始化时,initialize()方法仅被调用一次,此时首次调用的性能至关重要。假设框架启动时调用8000个方法,每个耗时1ms,总耗时8秒,而枚举switch比if多增加0.6ms开销,这是不合理的。因此我想询问,该性能开销的根源是什么?

内容的提问来源于stack exchange,提问作者Mr Monitor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 08:42:44