рд╕реА # рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВ ?: рдмрдирд╛рдо рдмрдирд╛рдо-рдЕрдиреНрдпрдерд╛ рд╕реНрд╡рд┐рдЪ

рдЖрдЬ, рдПрдХ рдФрд░ рдкрд╢реБ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреА рд╕рдореАрдХреНрд╖рд╛ рдореЗрдВ рдЙрдбрд╝рд╛рди рднрд░реА:

public static class AnimalsFactory
{
    public static Animal CreateAnimalByTernaryOperator(bool isCat)
    {
        return isCat ? (Animal)new Cat() : new Dog();
    }
}

рдПрдХ рдмрд╛рд░ рдлрд┐рд░ рдореИрдВ рдкрд░реЗрд╢рд╛рди рдерд╛ рдХрд┐ C # рдЖрдкрдХреЛ рдПрдирд┐рдорд▓ рдХреЗ рд▓рд┐рдП рдХреИрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЬрд╛рддрд┐ рдХреЛ рдмреЗрд╣рддрд░ рд╣реЛрдиреЗ рджреЛ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдЧрд░-рдФрд░ рдХреЗ рдмрдпрд╛рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЛрдб рдФрд░ рднреА рд▓рдВрдмрд╛ рд╣реИ:
public static class AnimalsFactory
{
    public static Animal CreateAnimalByIfElseOperator(bool isCat)
    {
        if (isCat)
            return new Cat();

        return new Dog();
    }
}

рд╕рдореАрдХреНрд╖рд╛ рд╕реЗ рдПрдХ рдорд┐рдирдЯ рдХреЗ рд▓рд┐рдП рдЦреБрджрд╛рдИ рдХрд░реЗрдВ рдФрд░ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ:

  • рдХреНрдпрд╛ рдЗрди рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ IL рдХреЛрдб рдЕрд▓рдЧ рд╣реЛрдЧрд╛?
  • рдХреНрдпрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд▓рд╛рдн рд╣реЛрдЧрд╛?


рдкрд╣рд▓реЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рд╣рд╛рдВ, IL-code рдЕрд▓рдЧ рд╣реИ, рдореИрдВ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рд╣реИред

рдЖрдЗрдП рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдореБрджреНрджреЗ рдкрд░ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдбреЙрдЯрдиреЗрдЯ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдХреЗ рд▓рд┐рдП рдирдЧреЗрдЯ рдкреИрдХреЗрдЬ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ рдФрд░ рдПрдХ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦреЗрдВ:

public class AnimalFactoryPerformanceTests
{
    [ParamsAllValues]
    public bool IsCat { get; set; }

    [Benchmark]
    public void CreateAnimalByTernaryOperator() =>
        AnimalsFactory.CreateAnimalByTernaryOperator(IsCat);

    [Benchmark]
    public void CreateAnimalByIfElseOperator() =>
        AnimalsFactory.CreateAnimalByIfElseOperator(IsCat);
}

рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдкрд░рд┐рдгрд╛рдо:

|                          | IsCat |     |
|------------------------------ |------ |---------:|
| CreateAnimalByTernaryOperator | False | 1.357 ns |
| CreateAnimalByTernaryOperator |  True | 1.655 ns |
|------------------------------ |------ |---------:|
|  CreateAnimalByIfElseOperator | False | 1.636 ns |
|  CreateAnimalByIfElseOperator |  True | 1.360 ns |

рдпрд╣ рдЖрд╢реНрдЪрд░реНрдп рдХреА рдмрд╛рдд рд╣реИ рдХрд┐ "рдПрдХ рдХреБрддреНрддреЗ рдХреЗ рд▓рд┐рдП" рдЯрд░реНрдирд░реА рддреЗрдЬреА рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ "рдПрдХ рдмрд┐рд▓реНрд▓реА рдХреЗ рд▓рд┐рдП" - рдЕрдЧрд░ рдПрдХ рдФрд░ рдмрдпрд╛рдиред
рд╣рдо рдЯреЗрд░реАрд░реА рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде рд╡рд┐рдзрд┐ рдХреЗ рдЖрдИрдПрд▓-рдХреЛрдб рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ:

CreateAnimalByTernaryOperator(bool isCat)
{
    IL_0000: ldarg.0      // isCat
    IL_0001: brtrue.s     IL_0009
    IL_0003: newobj       instance void AnimalPerformance.Dog::.ctor()
    IL_0008: ret
    IL_0009: newobj       instance void AnimalPerformance.Cat::.ctor()
    IL_000e: ret
}

рдбреЙрдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╕рдордп, IL_0000 - IL_0008 рдХрдорд╛рдВрдб рдХреЛ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ , рдЬрдмрдХрд┐ рдХреИрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╕рдордп , рдПрдХ рд╕рд╢рд░реНрдд рдЫрд▓рд╛рдВрдЧ рд╣реЛрддреА рд╣реИ ( IL_0001: brtrue.s IL_0009 )ред

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдЧрд░-рдФрд░ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХреЗ рд▓рд┐рдП, рдЖрдИрдПрд▓ рдХреЛрдб рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдХреИрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╢рд░реНрдд рдХреВрджрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ ред рдЬрдмрдХрд┐ рдбреЙрдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдПрдХ рд╕рд╢рд░реНрдд рд╢рд╛рдЦрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:

CreateAnimalByIfElseOperator(bool isCat)
{
    IL_0000: ldarg.0      // isCat
    IL_0001: brfalse.s    IL_0009
    IL_0003: newobj       instance void AnimalPerformance.Cat::.ctor()
    IL_0008: ret
    IL_0009: newobj       instance void AnimalPerformance.Dog::.ctor()
    IL_000e: ret
}

рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рд╕реНрд╡рд┐рдЪ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХреЗ рд╕рд╛рде рддреЛрддрд╛ рдирд┐рд░реНрдорд╛рдг рдФрд░ рдПрдХ рдирдИ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ :

public static class AnimalFactory
{
    public static Animal CreateAnimalByTernaryOperator(AnimalType animalType)
    {
        return animalType == AnimalType.Cat
            ? new Cat()
            : animalType == AnimalType.Dog
                ? (Animal)new Dog()
                : new Parrot();
    }

    public static Animal CreateAnimalByIfElseOperator(AnimalType animalType)
    {
        if (animalType == AnimalType.Cat)
            return new Cat();

        if (animalType == AnimalType.Dog)
            return new Dog();

        return new Parrot();
    }

    public static Animal CreateAnimalBySwitchOperator(AnimalType animalType)
    {
        switch (animalType)
        {
            case AnimalType.Cat:
                return new Cat();
            case AnimalType.Dog:
                return new Dog();
            case AnimalType.Parrot:
                return new Parrot();
            default:
                throw new InvalidOperationException();
        }
    }
}

рдХреМрди рд╕реА рд╡рд┐рдзрд┐ рддреЗрдЬ рд╣реЛрдЧреА?

рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдкрд░рд┐рдгрд╛рдо
|                          | AnimalType |     |
|------------------------------ |----------- |---------:|
| CreateAnimalByTernaryOperator |        Cat | 2.490 ns |
| CreateAnimalByTernaryOperator |        Dog | 2.515 ns |
| CreateAnimalByTernaryOperator |     Parrot | 2.333 ns |
|------------------------------ |----------- |---------:|
|  CreateAnimalByIfElseOperator |        Cat | 2.368 ns |
|  CreateAnimalByIfElseOperator |        Dog | 2.545 ns |
|  CreateAnimalByIfElseOperator |     Parrot | 2.735 ns |
|------------------------------ |----------- |---------:|
|  CreateAnimalBySwitchOperator |        Cat | 2.747 ns |
|  CreateAnimalBySwitchOperator |        Dog | 2.730 ns |
|  CreateAnimalBySwitchOperator |     Parrot | 2.722 ns |


рдЖрдИрдПрд▓ рдХреЛрдб
CreateAnimalByTernaryOperator(AnimalsFactory.AnimalType animalType)
{
    IL_0000: ldarg.0      // animalType
    IL_0001: brfalse.s    IL_0013
    IL_0003: ldarg.0      // animalType
    IL_0004: ldc.i4.1
    IL_0005: beq.s        IL_000d
    IL_0007: newobj       instance void AnimalsFactory.Parrot::.ctor()
    IL_000c: ret
    IL_000d: newobj       instance void AnimalsFactory.Dog::.ctor()
    IL_0012: ret
    IL_0013: newobj       instance void AnimalsFactory.Cat::.ctor()
    IL_0018: ret
}

CreateAnimalByIfElseOperator(AnimalsFactory.AnimalType animalType)
{
    IL_0000: ldarg.0      // animalType
    IL_0001: brtrue.s     IL_0009
    IL_0003: newobj       instance void AnimalsFactory.Cat::.ctor()
    IL_0008: ret
    IL_0009: ldarg.0      // animalType
    IL_000a: ldc.i4.1
    IL_000b: bne.un.s     IL_0013
    IL_000d: newobj       instance void AnimalsFactory.Dog::.ctor()
    IL_0012: ret
    IL_0013: newobj       instance void AnimalsFactory.Parrot::.ctor()
    IL_0018: ret

}

CreateOtherAnimalBySwitchOperator(AnimalsFactory.AnimalType animalType)
{
    IL_0000: ldarg.0      // animalType
    IL_0001: switch       (IL_0014, IL_001a, IL_0020)
    IL_0012: br.s         IL_0026
    IL_0014: newobj       instance void AnimalsFactory.Cat::.ctor()
    IL_0019: ret
    IL_001a: newobj       instance void AnimalsFactory.Dog::.ctor()
    IL_001f: ret
    IL_0020: newobj       instance void AnimalsFactory.Parrot::.ctor()
    IL_0025: ret
    IL_0026: newobj       instance void System.InvalidOperationException::.ctor()
    IL_002b: throw
}


рдирд┐рд╖реНрдХрд░реНрд╖ 1: рдЯрд░реНрдирд░реА рдФрд░ рдпрджрд┐-рдЕрдиреНрдп рдХрдердиреЛрдВ рдХреЗ рд▓рд┐рдП, рд░рдирдЯрд╛рдЗрдо рд╕реАрдзреЗ рд╕рд╢рд░реНрдд рдЬрдВрдк рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдирд┐рд╖реНрдкрд╛рджрди рдереНрд░реЗрдб рдореЗрдВ рдкрд╛рд░рд┐рдд рд╣реЛ рдЧрдП рд╣реИрдВред

рдирд┐рд╖реНрдХрд░реНрд╖ 2: C # рд╕реНрд╡рд┐рдЪ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ IL рдХреЛрдб рдореЗрдВ рдПрдХ рд╕реНрд╡рд┐рдЪ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░, рдФрд╕рддрди, рдирд┐рдпрдорд┐рдд рдмреНрд░рд╛рдВрдЪрд┐рдВрдЧ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯреНрд╕ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдереЛрдбрд╝реА рдЕрдзрд┐рдХ рджреЗрд░ рддрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖ 3: рдЙрдкрд░реЛрдХреНрдд рд╕рдм рдХреБрдЫ рдХреЗрд╡рд▓ .NET рдлреНрд░реЗрдорд╡рд░реНрдХ v.4.8 рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИред .NetCore рдкрд░ рдПрдХ рд╣реА рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓реЗ рд╣реИрдВ рдЬрд┐рдирдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдЕрднреА рддрдХ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдХреА рдЬрд╛рдиреА рд╣реИред

рдмреЗрдВрдЪрдорд╛рд░реНрдХ .NetCore 3.0
|                          | AnimalType |     |
|------------------------------ |----------- |---------:|
| CreateAnimalByTernaryOperator |        Cat | 3.046 ns |
| CreateAnimalByTernaryOperator |        Dog | 2.984 ns |
| CreateAnimalByTernaryOperator |     Parrot | 3.019 ns |
|------------------------------ |----------- |---------:|
|  CreateAnimalByIfElseOperator |        Cat | 2.980 ns |
|  CreateAnimalByIfElseOperator |        Dog | 2.977 ns |
|  CreateAnimalByIfElseOperator |     Parrot | 3.103 ns |
|------------------------------ |----------- |---------:|
|  CreateAnimalBySwitchOperator |        Cat | 3.519 ns |
|  CreateAnimalBySwitchOperator |        Dog | 3.533 ns |
|  CreateAnimalBySwitchOperator |     Parrot | 3.312 ns |


рдкреНрд░реЛрд╕реЗрд╕рд░: Intel┬о Core (TM) i7-7700K

рд╕реНрд░реЛрдд

All Articles