Skip to content

Instantly share code, notes, and snippets.

@fny
Created September 10, 2012 22:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fny/3694560 to your computer and use it in GitHub Desktop.
Save fny/3694560 to your computer and use it in GitHub Desktop.
Loops and Variable Declaration Location Comparison with Java Bytecode
class HelloWorldLoops {
void stringDeclaredInsideLoop(){
while (true) {
String greeting = "Hello World!";
doNothing(greeting);
}
}
void stringDeclaredOutsideLoop(){
String greeting;
while (true) {
greeting = "Hello World!";
doNothing(greeting);
}
}
void stringAsDirectArgument(){
while (true) {
doNothing("Hello World!");
}
}
private void doNothing(String s) {
}
}
class HelloWorldLoopsAnnotated {
//
// HelloWorldLoopsAnnotated();
// Code:
// 0: aload_0
// 1: invokespecial #1; //Method java/lang/Object."<init>":()V
// 4: return
////////////////////////////////////////////////////////////////////////////
void stringDeclaredInsideLoop(){
while (true) {
0: ldc #2; //String Hello World!
String greeting = "Hello World!";
doNothing(greeting);
}
}
//
// void stringDeclaredInsideLoop();
// Code:
// 0: ldc #2; //String Hello World!
// 2: astore_1
// 3: aload_0
// 4: aload_1
// 5: invokespecial #3; //Method doNothing:(Ljava/lang/String;)V
// 8: goto 0
////////////////////////////////////////////////////////////////////////////
void stringDeclaredOutsideLoop(){
String greeting;
while (true) {
greeting = "Hello World!";
doNothing(greeting);
}
}
//
// void stringDeclaredOutsideLoop();
// Code:
// 0: ldc #2; //String Hello World!
// 2: astore_1
// 3: aload_0
// 4: aload_1
// 5: invokespecial #3; //Method doNothing:(Ljava/lang/String;)V
// 8: goto 0
////////////////////////////////////////////////////////////////////////////
void stringAsDirectArgument(){
while (true) {
doNothing("Hello World!");
}
}
// void stringAsDirectArgument();
// Code:
// 0: aload_0
// 1: ldc #2; //String Hello World!
// 3: invokespecial #3; //Method doNothing:(Ljava/lang/String;)V
// 6: goto 0
////////////////////////////////////////////////////////////////////////////
private void doNothing(String s) {
}
}
class HelloWorldLoops extends java.lang.Object{
HelloWorldLoops();
  Code:
   0:	aload_0
   1:	invokespecial	#1; //Method java/lang/Object."<init>":()V
   4:	return

void stringDeclaredInsideLoop();
  Code:
   0:	ldc	#2; //String Hello World!
   2:	astore_1
   3:	aload_0
   4:	aload_1
   5:	invokespecial	#3; //Method doNothing:(Ljava/lang/String;)V
   8:	goto	0

void stringDeclaredOutsideLoop();
  Code:
   0:	ldc	#2; //String Hello World!
   2:	astore_1
   3:	aload_0
   4:	aload_1
   5:	invokespecial	#3; //Method doNothing:(Ljava/lang/String;)V
   8:	goto	0

void stringAsDirectArgument();
  Code:
   0:	aload_0
   1:	ldc	#2; //String Hello World!
   3:	invokespecial	#3; //Method doNothing:(Ljava/lang/String;)V
   6:	goto	0
}
@fny
Copy link
Author

fny commented Sep 10, 2012

stringDeclaredInsideLoop() and stringDeclaredOutsideLoop() yield identical six-instruction bytecode. stringDeclaredInsideLoop() does still win: limited scope is best.

After some contemplation, I can't really see how tightening scope ever affecting performance; identical data in the stack would necessitate identical instructions.

stringAsDirectArgument(), however, defines the operation in only four instructions. Low memory environments (e.g. my magnificently dumb phone) may appreciate the optimization while a colleague reading your code may not, so exercise judgement before shaving bytes from your code.

You can compile the class above with javac HelloWorldLoops.java and dump the bytecode with javap -c HelloWorldLoops. You can also dig deeper with javap -verbose HelloWorldLoops.
The above code was generated using Java version 1.6.0_33.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment