Do long type names significantly affect performance?

A type name like com.example.Dog will be compiled into com/example/Dog in the .class file. How do most JVMs optimize it? It seems that longer type names (or member names) require more lines.

+4
source share
3 answers

Names of the long type (class and interface) take up space in the symbol tables. Names are used in time binding, as described in detail in Chapter 5 of the Java Virtual Machine Specification . After all this is done, the names do not affect the performance at runtime unless you use reflection.

+8
source

java compiler generates bytecode, no string comparison.

check this class using javap and see the bytecode.

For example, this

 class A extends java.lang.Object{ static final boolean $assertionsDisabled; A(); public static void main(java.lang.String[]); static {}; } 

turn on this

 class A extends java.lang.Object{ static final boolean $assertionsDisabled; A(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field $assertionsDisabled:Z 3: ifne 14 6: new #3; //class java/lang/AssertionError 9: dup 10: invokespecial #4; //Method java/lang/AssertionError."<init>":()V 13: athrow 14: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream; 17: ldc #6; //String hi 19: invokevirtual #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 22: return static {}; Code: 0: ldc_w #8; //class A 3: invokevirtual #9; //Method java/lang/Class.desiredAssertionStatus:()Z 6: ifne 13 9: iconst_1 10: goto 14 13: iconst_0 14: putstatic #2; //Field $assertionsDisabled:Z 17: return } 

inside jvm uses numeric identifiers. there is no difference between long and short variable names.

edit: add -l output

 Compiled from "A.java" class A extends java.lang.Object{ static final boolean $assertionsDisabled; A(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 3: 0 public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field $assertionsDisabled:Z 3: ifne 14 6: new #3; //class java/lang/AssertionError 9: dup 10: invokespecial #4; //Method java/lang/AssertionError."<init>":()V 13: athrow 14: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream; 17: ldc #6; //String hi 19: invokevirtual #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 22: return LineNumberTable: line 6: 0 line 7: 14 line 8: 22 static {}; Code: 0: ldc_w #8; //class A 3: invokevirtual #9; //Method java/lang/Class.desiredAssertionStatus:()Z 6: ifne 13 9: iconst_1 10: goto 14 13: iconst_0 14: putstatic #2; //Field $assertionsDisabled:Z 17: return LineNumberTable: line 3: 0 } 

and add -verbose -s

 Compiled from "A.java" class A extends java.lang.Object SourceFile: "A.java" minor version: 0 major version: 50 Constant pool: const #1 = Method #10.#23; // java/lang/Object."<init>":()V const #2 = Field #8.#24; // A.$assertionsDisabled:Z const #3 = class #25; // java/lang/AssertionError const #4 = Method #3.#23; // java/lang/AssertionError."<init>":()V const #5 = Field #26.#27; // java/lang/System.out:Ljava/io/PrintStream; const #6 = String #28; // hi const #7 = Method #29.#30; // java/io/PrintStream.println:(Ljava/lang/String;)V const #8 = class #31; // A const #9 = Method #32.#33; // java/lang/Class.desiredAssertionStatus:()Z const #10 = class #34; // java/lang/Object const #11 = Asciz $assertionsDisabled; const #12 = Asciz Z; const #13 = Asciz <init>; const #14 = Asciz ()V; const #15 = Asciz Code; const #16 = Asciz LineNumberTable; const #17 = Asciz main; const #18 = Asciz ([Ljava/lang/String;)V; const #19 = Asciz StackMapTable; const #20 = Asciz <clinit>; const #21 = Asciz SourceFile; const #22 = Asciz A.java; const #23 = NameAndType #13:#14;// "<init>":()V const #24 = NameAndType #11:#12;// $assertionsDisabled:Z const #25 = Asciz java/lang/AssertionError; const #26 = class #35; // java/lang/System const #27 = NameAndType #36:#37;// out:Ljava/io/PrintStream; const #28 = Asciz hi; const #29 = class #38; // java/io/PrintStream const #30 = NameAndType #39:#40;// println:(Ljava/lang/String;)V const #31 = Asciz A; const #32 = class #41; // java/lang/Class const #33 = NameAndType #42:#43;// desiredAssertionStatus:()Z const #34 = Asciz java/lang/Object; const #35 = Asciz java/lang/System; const #36 = Asciz out; const #37 = Asciz Ljava/io/PrintStream;; const #38 = Asciz java/io/PrintStream; const #39 = Asciz println; const #40 = Asciz (Ljava/lang/String;)V; const #41 = Asciz java/lang/Class; const #42 = Asciz desiredAssertionStatus; const #43 = Asciz ()Z; { static final boolean $assertionsDisabled; Signature: Z A(); Signature: ()V LineNumberTable: line 3: 0 Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 3: 0 public static void main(java.lang.String[]); Signature: ([Ljava/lang/String;)V LineNumberTable: line 6: 0 line 7: 14 line 8: 22 Code: Stack=2, Locals=1, Args_size=1 0: getstatic #2; //Field $assertionsDisabled:Z 3: ifne 14 6: new #3; //class java/lang/AssertionError 9: dup 10: invokespecial #4; //Method java/lang/AssertionError."<init>":()V 13: athrow 14: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream; 17: ldc #6; //String hi 19: invokevirtual #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 22: return LineNumberTable: line 6: 0 line 7: 14 line 8: 22 StackMapTable: number_of_entries = 1 frame_type = 14 /* same */ static {}; Signature: ()V LineNumberTable: line 3: 0 Code: Stack=1, Locals=0, Args_size=0 0: ldc_w #8; //class A 3: invokevirtual #9; //Method java/lang/Class.desiredAssertionStatus:()Z 6: ifne 13 9: iconst_1 10: goto 14 13: iconst_0 14: putstatic #2; //Field $assertionsDisabled:Z 17: return LineNumberTable: line 3: 0 StackMapTable: number_of_entries = 2 frame_type = 13 /* same */ frame_type = 64 /* same_locals_1_stack_item */ stack = [ int ] } 
+5
source

This partly depends on whether it is possible to enable a real accurate method at compile time of JIT. If possible, it is possible that the compiled code simply jumps to the corresponding code. For example, you can see evidence that Hotspot does this in these timings for final vs non-final method calls . In fact, such optimization does not exist specifically for the final methods (this is a common misconception that I found among developers). But, as these numbers show, there is an optimization for cases where the exact method can be identified, final or not.

If the exact method cannot be identified, then the VM can at least work with the hash codes of the method signatures, so once the hash code has been calculated once for a call made from the given bytecode offset of this method, it will not be necessary count again. I admit, I did not see if Hotspot or other JVMs actually do this, but in principle it looks dazzlingly obvious.

+1
source

Source: https://habr.com/ru/post/1413103/


All Articles