1

I'm trying to find out how similar these two loops are when compiled:

for (int i = 0; i < result.length; i++){
   result[i] = array[((i < index) ? i : i + 1)];
}

and

for (int i = 0; i < result.length; i++){
   if(i < index) result[i] = array[i];
   else result[i] = array[i + 1];
}

I'm finding it difficult to single out where each loop's operations are.
How should I go about comparing these two loops? Thanks

Here's what I got when I ran the program using javap -c:

Compiled from "Test.java"
public class Test {
  public Test();
    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 Test
       3: dup           
       4: invokespecial #3                  // Method "<init>":()V
       7: pop           
       8: return        

  public void Test();
    Code:
       0: bipush        10
       2: newarray       int
       4: astore_1      
       5: iconst_0      
       6: istore_2      
       7: iload_2       
       8: bipush        10
      10: if_icmpge     23
      13: aload_1       
      14: iload_2       
      15: iload_2       
      16: iastore       
      17: iinc          2, 1
      20: goto          7
      23: aload_0       
      24: aload_1       
      25: iconst_5      
      26: invokespecial #4                  // Method removeAndTrimConcise:([II)[I
      29: pop           
      30: bipush        10
      32: newarray       int
      34: astore_1      
      35: iconst_0      
      36: istore_2      
      37: iload_2       
      38: bipush        10
      40: if_icmpge     53
      43: aload_1       
      44: iload_2       
      45: iload_2       
      46: iastore       
      47: iinc          2, 1
      50: goto          37
      53: aload_0       
      54: aload_1       
      55: iconst_5      
      56: invokespecial #5                  // Method removeAndTrim:([II)[I
      59: pop           
      60: return        
}
4
  • What kind of comparison do you mean? Performance? Commented Jan 26, 2012 at 10:06
  • Yeah, because when doing huge amounts of iteration their millisecond performance seems to favor the second loop (not in-line conditional) almost every time. Yet looking at the answer below they seem to be identical after compiling? Commented Jan 26, 2012 at 10:10
  • "Huge amounts of iteration? Is this real? Have you profiled it? Do you think that a change in algorithm, like parallelizing it, might be worth more effort than this particular change? Commented Jan 26, 2012 at 10:28
  • What I meant was doing the same exact loop millions of times for testing purposes. Realistically / in practice it would have minimal effect, but I'm sure you can understand the need to squeeze something to its limits sometimes. :p Commented Jan 26, 2012 at 10:40

3 Answers 3

3

Should be roughly between newarray (I assume you are creating a new array before each loop) and goto (which, as you can see, brings the control flow back up to a previous line, hence looping):

First loop:

   2: newarray       int
   4: astore_1      
   5: iconst_0      
   6: istore_2      
   7: iload_2       
   8: bipush        10
  10: if_icmpge     23
  13: aload_1       
  14: iload_2       
  15: iload_2       
  16: iastore       
  17: iinc          2, 1
  20: goto          7

second:

  32: newarray       int
  34: astore_1      
  35: iconst_0      
  36: istore_2      
  37: iload_2       
  38: bipush        10
  40: if_icmpge     53
  43: aload_1       
  44: iload_2       
  45: iload_2       
  46: iastore       
  47: iinc          2, 1
  50: goto          37

They seem to be pretty much identical.

Sign up to request clarification or add additional context in comments.

1 Comment

@paranoid-android: Honestly, I'm not an expert on bytecode, but for the goto it's definitely the instruction to jump back to, for the if_icmpge it's the same (jump after goto if the condition is false). You can find a listing of instructions and parameters here: en.wikipedia.org/wiki/Java_bytecode_instruction_listings
2

Put them in two separate files where the only difference is the loop. Rerun javap and compare.

But the real answer, beyond satisfying your curiosity, is "it doesn't matter". There's no performance optimization. You should write the one that's clearer and more readable. It's partly a matter of taste. My preference is the ternary operator.

1 Comment

I agree completely. I've never compared bytecode before which is why I was confused by it. I tend to prefer concise over readable if I know the alg / logic is concrete and the function is clear. Thanks though.
1

I suggest compiling the program once with one loop and once with the other loop. Alternatively, make 2 methods and label them with the type of loop you're gonna use, then compile them. Copy-pasta in Text Diff http://www.textdiff.com/ to easy see the difference between the two.

This will remove any issues of compiler-optimization for a repeated loop (I don't know enough about the subject to say that this can happen, but I think it could).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.