论String操作时间复杂度 Java综合
程序员文章站
2022-06-08 12:49:12
...
面试题
以下类中,method1和method2的时间复杂度一样吗?为什么。
我当时的回答是应该一样,因为我实在找不出说明他们不一样的地方。但是面试官这么问肯定有原因的,我只是从效率方面来分析,比如说method1会通过StringBuilder来做,没有后面method2好。后来面试官纠正了提问,说从时间复杂度来考虑。我直接跟他说了,我只能看出是一样的,可能method2会更好些。面试官好像不是很满意。
回来我从源码着手看,感觉不靠谱,后来看到有人分析用字节码来看。可以看到编译器怎么翻译的。经过证实,跟我的想法一样。字节码如下:
以下类中,method1和method2的时间复杂度一样吗?为什么。
public class Test { public static final int MB = 1024 * 1024; public static final long TIMES = 500000000L; public static void main(String[] args) throws InterruptedException { method1(); method2(); } //从字节码来看,method1重复new StringBuilder 然后append,显然不高效。这里排除jit优化。 public static void method1() { String s = ""; for (int i = 0; i < 100; i++) { s += "a"; } System.out.println(s); } public static void method2() { // //b StringBuilder sb = new StringBuilder(); for (int i = 0; i < 100; i++) { sb.append("a"); } System.out.println(sb.toString()); } }
我当时的回答是应该一样,因为我实在找不出说明他们不一样的地方。但是面试官这么问肯定有原因的,我只是从效率方面来分析,比如说method1会通过StringBuilder来做,没有后面method2好。后来面试官纠正了提问,说从时间复杂度来考虑。我直接跟他说了,我只能看出是一样的,可能method2会更好些。面试官好像不是很满意。
回来我从源码着手看,感觉不靠谱,后来看到有人分析用字节码来看。可以看到编译器怎么翻译的。经过证实,跟我的想法一样。字节码如下:
Compiled from "Test.java" public class Test extends java.lang.Object{ public static final int MB; public static final long TIMES; public Test(); Code: 0: aload_0 1: invokespecial #16; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.lang.InterruptedException; Code: 0: invokestatic #27; //Method method1:()V 3: invokestatic #30; //Method method2:()V 6: return public static void method1(); Code: 0: ldc #35; //String 2: astore_0 3: iconst_0 4: istore_1 5: goto 31 8: new #37; //class java/lang/StringBuilder 11: dup 12: aload_0 13: invokestatic #39; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 16: invokespecial #45; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 19: ldc #48; //String a 21: invokevirtual #50; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: invokevirtual #54; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 27: astore_0 28: iinc 1, 1 31: iload_1 32: bipush 100 34: if_icmplt 8 37: getstatic #58; //Field java/lang/System.out:Ljava/io/PrintStream; 40: aload_0 41: invokevirtual #64; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 44: return public static void method2(); Code: 0: new #37; //class java/lang/StringBuilder 3: dup 4: invokespecial #73; //Method java/lang/StringBuilder."<init>":()V 7: astore_0 8: iconst_0 9: istore_1 10: goto 23 13: aload_0 14: ldc #48; //String a 16: invokevirtual #50; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: pop 20: iinc 1, 1 23: iload_1 24: bipush 100 26: if_icmplt 13 29: getstatic #58; //Field java/lang/System.out:Ljava/io/PrintStream; 32: aload_0 33: invokevirtual #54; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 36: invokevirtual #64; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 39: return }