Is it faster (or better) to declare array inlining in Java?
Consider the following two almost equal method calls Notice how byte arrays are declared and allocated on both
void Method1() { byte [] bytearray = new byte[16]; /* some code */ } void Method2() { byte [] bytearray = {0,0}; /* some code */ }
In both cases, assume that "bytearray" is a candidate for garbage collection when method1 and method2 return, because any code that manipulates the tearray variable will not retain a reference at the end of the method itself
Does method2 avoid faster (or different) operations on "new" calls? Or more than two implementations? In both cases, the java compiler or runtime can be optimized to avoid the overhead of memory allocators for short temporary buffers
Solution
Which form is the fastest? Depends on JIT – they may be equivalent If so, few programs will notice a difference
Which form is the best? It almost always makes your program easier to read
But what's the real difference, whether we notice it or not? Let's have a look!
class ArrayTest { public int[] withNew() { int[] arr = new int[4]; return arr; } public int[] withInitializer() { int[] arr = {0,0}; return arr; } }
We use javap - C ARRAYTEST to disassemble:
Compiled from "ArrayTest.java" class ArrayTest { Arraytest(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public int[] withNew(); Code: 0: iconst_4 1: newarray int 3: astore_1 4: aload_1 5: areturn public int[] withInitializer(); Code: 0: iconst_4 1: newarray int 3: dup 4: iconst_0 5: iconst_0 6: iastore 7: dup 8: iconst_1 9: iconst_0 10: iastore 11: dup 12: iconst_2 13: iconst_0 14: iastore 15: dup 16: iconst_3 17: iconst_0 18: iastore 19: astore_1 20: aload_1 21: areturn }
No, in this case, they are different - using the initializer form will cause the slots to be set to 0 separately, because they have been configured to zero by the array, which is meaningless Therefore, this is basically equivalent to:
public int[] withNewAndSettingExplicitly() { int[] arr = new int[4]; arr[0] = 0; arr[1] = 0; arr[2] = 0; arr[3] = 0; return arr; }
Although another set of bytecodes is compiled, this is almost the same but not exactly the same:
public int[] withNewAndSettingExplicitly(); Code: 0: iconst_4 1: newarray int 3: astore_1 4: aload_1 5: iconst_0 6: iconst_0 7: iastore 8: aload_1 9: iconst_1 10: iconst_0 11: iastore 12: aload_1 13: iconst_2 14: iconst_0 15: iastore 16: aload_1 17: iconst_3 18: iconst_0 19: iastore 20: aload_1 21: areturn
Therefore, the moral of the story is this: if you want all elements to be set to 0, use the new int [size] (this may or may not be faster) to generate less bytecode, but you must also enter less IMHO, which is a big victory) If you want to set the values in the array directly in the array, use the best code in the code, because the generated code will be almost the same as the form you choose
Now, answer your practical questions:
As we can see, the new is just hidden behind the initializer syntax (looking for newarray op code) By the way, allocation is very cheap in the JVM (generation garbage collectors have this pleasant side effect)
As we can see - not exactly the same, but it's unlikely that anyone will notice the difference
Again – distribution is cheap, so don't worry However, recent JVMs have such a small feature called escape analysis, which may lead to array allocation rather than heap allocation