1. C# / Говнокод #22608

    −11

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    public static bool IsPositiveInfinity(double d) 
    {
                //Jit will generate inlineable code with this
                if (d == double.PositiveInfinity)
                {
                            return true;
                }
                else
                {
                            return false;
                }
    }

    Так быстрее, ибо JIT

    Взято из стандартной библиотеки .NET

    Запостил: dm_fomenok, 18 Марта 2017

    Комментарии (16) RSS

    • Кстати, конкурс: кто проверит это утверждение в няшном сишарпике, тому пирожок с полки
      Ответить
      • фикус заключается в том что JIT у мелкомагких меняет много кода на лету на нативный код и то что вы видите не значит то что он будет выполнять :)
        Ответить
      • Проверил. Одновозвратный код приводит к лишним джампам в нативном образе по сравнению с длинным кодом:
        http://govnokod.ru/22608#comment377918

        Где мой пирожок?
        Ответить
    • Компилятор генерирует код типа такого:
      IL_0000:  nop
          IL_0001:  ldarg.0
          IL_0002:  ldc.r8     (00 00 00 00 00 00 F0 7F)
          IL_000b:  ceq
          IL_000d:  stloc.0
          IL_000e:  ldloc.0
          IL_000f:  brfalse.s  IL_0016
      
          IL_0011:  nop
          IL_0012:  ldc.i4.1
          IL_0013:  stloc.1
          IL_0014:  br.s       IL_001b
      
          IL_0016:  nop
          IL_0017:  ldc.i4.0
          IL_0018:  stloc.1
          IL_0019:  br.s       IL_001b
      
          IL_001b:  ldloc.1
          IL_001c:  ret

      Если же записать короче, вот так, например:
      return (d == double.PositiveInfinity);

      То компилятор сгенерирует более короткий код:
      IL_0000:  nop
          IL_0001:  ldarg.0
          IL_0002:  ldc.r8     (00 00 00 00 00 00 F0 7F)
          IL_000b:  ceq
          IL_000d:  stloc.0
          IL_000e:  br.s       IL_0010
      
          IL_0010:  ldloc.0
          IL_0011:  ret

      Неужели первый вариант лучше?
      Ответить
      • # br.s IL_0010

        Зачем безусловный переход на следующую команду?
        Ответить
        • все забыли что JIT оптемизирует уже скомпиляный код. и то что вы видите не имеет смысла анализировать на производительность потому что он будет просто упрошен просле прогонки JITом
          Ответить
          • # все забыли

            Но не я
            Ответить
          • Сгенерировал нативный образ. Из исходного кода с ифом получилось это (нопы опустил):
            fld     [esp+arg_0]
            fld     ds:positiveinfinity
            fcomip  st, st(1)
            fstp    st
            jp      short loc_1
            jnz     short loc_1
            mov     eax, 1
            retn    8
            loc_1:
            xor     eax, eax
            retn    8


            Из кода с одним ретурном и без ифа (return (d == double.PositiveInfinity);) получилось это:
            fld     [esp+arg_0]
            fld     ds:positiveinfinity
            fcomip  st, st(1)
            fstp    st
            jp      short loc_2
            jz      short loc_3
            jmp     short $+2
            loc_2:                           
            xor     eax, eax
            jmp     short locret
            loc_3:
            mov     eax, 1
            locret:
            retn    8


            И правда, плохой код лучше оптимизируется JIT'ом, чем хороший.
            Ответить
        • Да ещё и магия stloc + ldloc, которая тупо копирует одно значение со стека в локальную переменную 0, которая теряется.

          После оптимизации (ключ /o+) этот кусок вырезается. Первый вариант:
          IL_0000:  ldarg.0
              IL_0001:  ldc.r8     (00 00 00 00 00 00 F0 7F)
              IL_000a:  bne.un.s   IL_000e
          
              IL_000c:  ldc.i4.1
              IL_000d:  ret
          
              IL_000e:  ldc.i4.0
              IL_000f:  ret

          Второй вариант:
          IL_0000:  ldarg.0
              IL_0001:  ldc.r8     (00 00 00 00 00 00 F0 7F)
              IL_000a:  ceq
              IL_000c:  ret


          if из приведённого говнокода не вырезается даже оптимизатором.
          Ответить
    • Чё эт за хуйня?
      Ответить
    • у Вас каптура плохая.
      Ответить

    Добавить комментарий