DESKTOP-4LGG1I2_20200829-周拉才让

问题

​ 今天在刷题时遇到这样一个问题,写的两段代码功能是相同的,但是,在效率上有很大的不同,第二段是我自己写的,第一段是经过改进后的,运行的结果一摸一样,但由于第二段的效率极差根本提交不了,改进后的经过十几毫秒就出结果了,为什么差别会这么大?

public boolean judgeCircle(String moves) {
        int x = 0, y = 0;
        int a = moves.length();
        for (int i = 0; i < a; i++) {
            char b = moves.charAt(i);//改进的代码
            switch (b) {
            case 'U':
                x++;
                break;
            case 'D':
                x--;
                break;
            case 'R':
                y++;
                break;
            case 'L':
                y--;
                break;
            }
            System.out.print("["+x+","+y+"]"+"\s");

        }
        System.out.println();
        return x == 0 && y == 0;
    }
public boolean judgeCircle(String moves) {
        int x = 0, y = 0;
        int a = moves.length();
        for (int i = 0; i < a; i++) {
            char[] b = moves.toCharArray();//原代码
            switch (b[i]) {
            case 'U':
                x++;
                break;
            case 'D':
                x--;
                break;
            case 'R':
                y++;
                break;
            case 'L':
                y--;
                break;
            }
            System.out.print("["+x+","+y+"]"+"\s");

        }
        System.out.println();
        return x == 0 && y == 0;
    }

解决

​ 事后在网上找了一下相关的文案,是堆内存的问题:charAt的调用会使栈帧加一层深度,经过两次index校验后,用index访问value数组,不会有额外的堆内存使用。而toCharArray的调用会在堆中创建了一个新的字符数组,把value字符数组都copy进去,之后访问新数组获取值。

通过相关代码的测试也得出了结论charAt的效率比toCharArray的高

测试代码

public class Solution {
    public static void test() {  
        String s = "a";  
        for(int i = 0; i < 100000; i++) {  
            s += "a";  
        }  
        /****************toCharArray遍历*************/  
        long start1 = System.currentTimeMillis();  
        char[] arr = s.toCharArray();  
        for (int i = 0; i < arr.length; i++) {
             char c = arr[i];
             System.out.println(c);
        }
        long end1 = System.currentTimeMillis();  
        /****************charAt遍历******************/    
        long start2 = System.currentTimeMillis();  
        for(int i = 0; i < s.length(); i++) {  
            char c = s.charAt(i);  
            System.out.println(c);  
        }  
        long end2 = System.currentTimeMillis();  
              
        System.out.println(end1 - start1);  //607
        System.out.println(end2 - start2);  //583
    }  
    public static void main(String[] args) {
        Solution.test();
    }
}

标签

© 2021 成都云创动力科技有限公司 蜀ICP备20006351号-1