Производительность <= и> = при использовании типов с плавающей запятой - PullRequest
1 голос
/ 10 июня 2019

Я слышал, что при использовании операторов <= или >= он автоматически оптимизируется компиляторами следующим образом: (int)Variable >= 2 становится (int)Variable > 1. Это правда в любом случае для типов с плавающей точкой? Мне кажется, что (float)Variable >= 2 нельзя оптимизировать до (float)Variable > 1.999999999, не отправляясь в бесконечность, что делает его невозможным или наносит ущерб производительности. (Я знаю, что разница в производительности может быть незначительной, но это просто то, что я хотел бы знать)

1 Ответ

1 голос
/ 10 июня 2019

Это не так, если вы проверяете сгенерированный код IL.Например, рассмотрим следующий класс:

public class C 
{
    public void M() 
    {
        float a = 4;
        float b = 5;
        bool result = a >= b;
    }
}

Сгенерированный код IL выглядит следующим образом:

.class public auto ansi beforefieldinit C
    extends [mscorlib]System.Object
{
    // Methods
    .method public hidebysig 
        instance void M () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 22 (0x16)
        .maxstack 2
        .locals init (
            [0] float32,
            [1] float32,
            [2] bool
        )

        IL_0000: nop
        IL_0001: ldc.r4 4
        IL_0006: stloc.0
        IL_0007: ldc.r4 5
        IL_000c: stloc.1
        IL_000d: ldloc.0
        IL_000e: ldloc.1
        IL_000f: clt.un
        IL_0011: ldc.i4.0
        IL_0012: ceq
        IL_0014: stloc.2
        IL_0015: ret
    } // end of method C::M

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x2072
        // Code size 8 (0x8)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: nop
        IL_0007: ret
    } // end of method C::.ctor

} // end of class C

Если вы прочитали выше сгенерированный код IL (используйте в качестве ссылки на ILкомандами this ), вы заметите, что это не так.

В нескольких словах в вышеприведенном коде IL числа float загружаются в стек, а затем clt.unиспользуется операция, которая:

Нажмите 1 (типа int32), если значение1 <значение2, без знака или неупорядочено, иначе нажмите 0. </p>

Тогда результат этой операциисравнивается на равенство с 0, используя ceq, что:

Нажмите 1 (типа int32), если значение1 равно значению 2, в противном случае нажмите 0.

иРезультат вышеизложенного присваивается результату variable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...