Использование Vim для редактирования файлов Microsoft Word

Как JohannesD предложил в комментарии , вряд ли можно считать от 0 до Integer.MAX_VALUE (и, после переполнения, от -Integer.MAX_VALUE до 0) так быстро.

Чтобы проверить предположение о том, что JIT выполняет некоторую магическую оптимизацию, я создал слегка модифицированную программу, внедрив некоторые методы, облегчающие идентификацию частей кода:

class IntOverflowTest
{
    public static void main(String[] args) {
        runLoop();
    }

    public static void runLoop()
    {
        int i = 1;
        int k = 0;
        while (true) {
            if(++i==0) doPrint(++k);
        }
    }

    public static void doPrint(int k)
    {
        System.out.println("loop: " + k);
    }

}

Байт-код, испускаемый и показанный с помощью javap -c IntOverflowTest, не вызывает удивления:

class IntOverflowTest {
  IntOverflowTest();
    Code:
       0: aload_0
       1: invokespecial #1                  
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #2                  
       3: return

  public static void runLoop();
    Code:
       0: iconst_1
       1: istore_0
       2: iconst_0
       3: istore_1
       4: iinc          0, 1
       7: iload_0
       8: ifne          4
      11: iinc          1, 1
      14: iload_1
      15: invokestatic  #3                  
      18: goto          4

  public static void doPrint(int);
    Code:
       0: getstatic     #4                  
       3: new           #5                  
       6: dup
       7: invokespecial #6                  
      10: ldc           #7                  
      12: invokevirtual #8                  
      15: iload_0
      16: invokevirtual #9                  
      19: invokevirtual #10                 
      22: invokevirtual #11                 
      25: return
}

Он явно увеличивает обе локальные переменные (runLoop, смещения 4 и 11).

Однако, при запуске кода с -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation -XX:+PrintAssembly в дизассемблере Hotspot, машинный код в итоге получается следующим:

Decoding compiled method 0x00000000025c2c50:
Code:
[Entry Point]
[Verified Entry Point]
[Constants]
  # {method} {0x000000001bb40408} 'runLoop' '()V' in 'IntOverflowTest'
  #           [sp+0x20]  (sp of caller)
  0x00000000025c2da0: mov    %eax,-0x6000(%rsp)
  0x00000000025c2da7: push   %rbp
  0x00000000025c2da8: sub    [112]x10,%rsp         ;*synchronization entry
                                                ; - IntOverflowTest::runLoop@-1 (line 10)

  0x00000000025c2dac: mov    [112]x1,%ebp          ;*iinc
                                                ; - IntOverflowTest::runLoop@11 (line 13)

  0x00000000025c2db1: mov    %ebp,%edx
  0x00000000025c2db3: callq  0x00000000024f6360  ; OopMap{off=24}
                                                ;*invokestatic doPrint
                                                ; - IntOverflowTest::runLoop@15 (line 13)
                                                ;   {static_call}
  0x00000000025c2db8: inc    %ebp               ;*iinc
                                                ; - IntOverflowTest::runLoop@11 (line 13)

  0x00000000025c2dba: jmp    0x00000000025c2db1  ;*invokestatic doPrint
                                                ; - IntOverflowTest::runLoop@15 (line 13)

  0x00000000025c2dbc: mov    %rax,%rdx
  0x00000000025c2dbf: add    [112]x10,%rsp
  0x00000000025c2dc3: pop    %rbp
  0x00000000025c2dc4: jmpq   0x00000000025b0d20  ;   {runtime_call}
  0x00000000025c2dc9: hlt

Можно ясно видеть, что он не увеличивается внешняя переменная i больше. Он вызывает только метод doPrint, увеличивает на единицу переменную (k в коде), а затем сразу же возвращается к точке, предшествующей вызову doPrint.

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

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

17
задан Gordon Gustafson 10 May 2015 в 16:25
поделиться

1 ответ

Это невозможно. Vim по своей природе является текстовым редактором и не предлагает стиль Microsoft Word WYSIWYG. Вы не можете редактировать отформатированные документы.

Конечно, вы можете отредактировать исходный код файла RTF (RTF - довольно простой язык форматирования, поэтому редактировать его вручную теоретически возможно), но я не делаю думаю, это то, что вы ищете.

Если вы хотите редактировать с помощью Vim, но по-прежнему производите документы с форматированием, ваш лучший снимок - LaTeX . Это позволяет создавать профессиональные документы с помощью языка программирования макросов.

17
ответ дан 30 November 2019 в 12:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: