Сравнивая байт-код Java для простого цикла? - PullRequest
1 голос
/ 26 января 2012

Я пытаюсь выяснить, насколько похожи эти два цикла при компиляции:

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

и

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

Мне трудно выделить, где выполняются операции каждого цикла.
Как мне сравнить эти две петли? Спасибо

Вот что я получил, когда запустил программу, используя 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        
}

Ответы [ 3 ]

3 голосов
/ 26 января 2012

Должно быть примерно между newarray (я предполагаю, что вы создаете новый массив перед каждым циклом) и goto (что, как вы можете видеть, возвращает поток управления к предыдущей строке, следовательно, цикл):

Первый цикл:

   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

второй:

  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

Кажется, они в значительной степени идентичны.

2 голосов
/ 26 января 2012

Поместите их в два отдельных файла, где единственным отличием является цикл. Запустите javap и сравните.

Но настоящий ответ, помимо удовлетворения вашего любопытства, это "это не имеет значения". Там нет оптимизации производительности. Вы должны написать более понятный и читаемый. Это частично вопрос вкуса. Я предпочитаю троичный оператор.

1 голос
/ 26 января 2012

Я предлагаю компилировать программу один раз с одним циклом и один раз с другим циклом.Или создайте 2 метода и пометьте их типом цикла, который вы собираетесь использовать, а затем скомпилируйте их.Copy-pasta в Text Diff http://www.textdiff.com/, чтобы легко увидеть разницу между ними.

Это устранит любые проблемы оптимизации компилятора для повторного цикла (я не знаю достаточно о предметесказать, что это может произойти, но я думаю, что это возможно).

...