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

为何在有效字母异位词解法中foreach循环比for循环更快?

为什么两次foreach遍历的解法比单次for循环更快?

我用下面的解法完成了LeetCode的**有效字母异位词(Valid Anagram)**问题,运行时长为4ms:

class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }

        int[] countArray = new int[26];
        char[] a = s.toCharArray();
        char[] b = t.toCharArray();
        for (int i = 0; i < s.length(); i++) {
            countArray[a[i] - 'a']++;
            countArray[b[i] - 'a']--;
        }

        for (int i = 0; i < 26; i++) {
            if (countArray[i] != 0) {
                return false;
            }
        }
        return true;
    }
}

但我看到有人使用foreach循环的解法仅耗时2ms:

class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }

        int[] countArray = new int[26];
        for (char ch : s.toCharArray()) {
            countArray[ch - 'a']++;
        }

        for (char ch : t.toCharArray()) {
            countArray[ch - 'a']--;
        }

        for (int count : countArray) {
            if (count != 0) {
                return false;
            }
        }
        return true;
    }
}

关键原因分析

  • 缓存局部性优势
    你的解法在单次循环中交替访问两个独立的char数组a和b,这种跨数组的随机访问会降低CPU缓存(L1/L2)的命中率——缓存更擅长处理连续内存地址的访问。而foreach解法是先连续遍历完第一个字符串的char数组,再连续遍历第二个,整个过程内存访问是连续的,缓存能高效命中,减少CPU等待内存数据的时间,整体执行速度更快。

  • JVM对foreach的编译优化
    Java中遍历数组的foreach循环会被编译器直接优化为高效的下标遍历,而且JVM的即时编译器(JIT)更容易对这种连续的单数组遍历做进一步优化,比如循环展开、指令重排,减少循环的额外开销。相比之下,你的手动for循环虽然逻辑上少一次遍历,但交替访问两个数组的操作让JVM难以做针对性优化。

  • 计时结果的参考性
    另外要注意,LeetCode的单次计时可能受服务器负载、JVM预热等因素影响存在误差,但如果多次测试都呈现foreach更快的结果,上面的缓存和编译优化就是核心原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 15:07:13