performance - What are the differences of explicit and implicit instantiating String class in java -
i have been told creating string instance this
string s = new string("don't this"); // explicit
has performance problem since creates 2 instance of string on double quoted phrase "don't this" , 1 new string() constructor!
today had time test self created 2 classes:
public class string1 { public static void main(string[] args) { string s = new string("hello"); system.out.println(s); } } public class string2 { public static void main(string[] args) { string s = "hello"; system.out.println(s); } }
here output of javap:
c:\jav>javap string1 compiled "string1.java" public class string1 extends java.lang.object{ public string1(); public static void main(java.lang.string[]); } c:\jav>javap string2 compiled "string2.java" public class string2 extends java.lang.object{ public string2(); public static void main(java.lang.string[]); }
seems same -c flag outputs deferent.
c:\jav>javap -c string1 compiled "string1.java" public class string1 extends java.lang.object{ public string1(); code: 0: aload_0 1: invokespecial #1; //method java/lang/object."<init>":()v 4: return public static void main(java.lang.string[]); code: 0: new #2; //class java/lang/string 3: dup 4: ldc #3; //string hello 6: invokespecial #4; //method java/lang/string."<init>":(ljava/lang/string;)v 9: astore_1 10: getstatic #5; //field java/lang/system.out:ljava/io/printstream; 13: aload_1 14: invokevirtual #6; //method java/io/printstream.println:(ljava/lang/string;)v 17: return } c:\jav>javap -c string2 compiled "string2.java" public class string2 extends java.lang.object{ public string2(); code: 0: aload_0 1: invokespecial #1; //method java/lang/object."<init>":()v 4: return public static void main(java.lang.string[]); code: 0: ldc #2; //string hello 2: astore_1 3: getstatic #3; //field java/lang/system.out:ljava/io/printstream; 6: aload_1 7: invokevirtual #4; //method java/io/printstream.println:(ljava/lang/string;)v 10: return }
so here questions :) first "ldc", astore_1 etc ? there documentation describing those? second javac can't figure out these 2 sentences equal??
wikipedia has convenient summary of possible java bytecode instructions. also, full picture, it's better use javap -v
, see entire content of file, including constant pool:
classfile /.../string1.class last modified 02/05/2013; size 458 bytes md5 checksum e3c355bf648c7441784ffc6b9765ba4d compiled "string1.java" public class string1 sourcefile: "string1.java" minor version: 0 major version: 51 flags: acc_public, acc_super constant pool: #1 = methodref #8.#17 // java/lang/object."<init>":()v #2 = class #18 // java/lang/string #3 = string #19 // hello #4 = methodref #2.#20 // java/lang/string."<init>":(ljava/l ang/string;)v #5 = fieldref #21.#22 // java/lang/system.out:ljava/io/prin tstream; #6 = methodref #23.#24 // java/io/printstream.println:(ljava /lang/string;)v #7 = class #25 // string1 #8 = class #26 // java/lang/object #9 = utf8 <init> #10 = utf8 ()v #11 = utf8 code #12 = utf8 linenumbertable #13 = utf8 main #14 = utf8 ([ljava/lang/string;)v #15 = utf8 sourcefile #16 = utf8 string1.java #17 = nameandtype #9:#10 // "<init>":()v #18 = utf8 java/lang/string #19 = utf8 hello #20 = nameandtype #9:#27 // "<init>":(ljava/lang/string;)v #21 = class #28 // java/lang/system #22 = nameandtype #29:#30 // out:ljava/io/printstream; #23 = class #31 // java/io/printstream #24 = nameandtype #32:#27 // println:(ljava/lang/string;)v #25 = utf8 string1 #26 = utf8 java/lang/object #27 = utf8 (ljava/lang/string;)v #28 = utf8 java/lang/system #29 = utf8 out #30 = utf8 ljava/io/printstream; #31 = utf8 java/io/printstream #32 = utf8 println { public string1(); flags: acc_public code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // method java/lang/object."<init> ":()v 4: return linenumbertable: line 1: 0 public static void main(java.lang.string[]); flags: acc_public, acc_static code: stack=3, locals=2, args_size=1 0: new #2 // class java/lang/string 3: dup 4: ldc #3 // string hello 6: invokespecial #4 // method java/lang/string."<init> ":(ljava/lang/string;)v 9: astore_1 10: getstatic #5 // field java/lang/system.out:ljav a/io/printstream; 13: aload_1 14: invokevirtual #6 // method java/io/printstream.prin tln:(ljava/lang/string;)v 17: return linenumbertable: line 3: 0 line 4: 10 line 5: 17 }
and it's clear ldc
loads constant.
regarding question why javac doesn't bother these optimizations - it's because entire optimization done on java deferred runtime, different compiler runs: jit compiler, compiles java bytecode native machine code. javac make effort optimize "common" cases, it's far aggressiveness of jitter.
Comments
Post a Comment