Страницы

Поиск по вопросам

среда, 5 февраля 2020 г.

Зависит ли время на создание объекта от количества его свойств и методов?

#c_sharp #net #производительность


Есть 2 класса:

public class MyClass
{
    public int Prop { get; set; }
}

public class MyClass2
{
    public int Prop1 { get; set; }
    public int Prop2 { get; set; }
    public int Prop3 { get; set; }
    public int Prop4 { get; set; }
    public int Prop5 { get; set; }
}


Конструкторы этих классов отработают за одинаковое количество времени или нет?
    


Ответы

Ответ 1



Исследования показали, что время выполнения конструктора зависит от количества памяти, выделяемой под экземпляр класса. Соответственно, поля и свойства с неявными get/set (как у вас) влияют, а методы и свойства с явными get/set не влияют (память под них в экземпляре не выделяется). using System; using System.Collections.Generic; using System.Diagnostics; namespace ConsoleTest { public class LittleClass { public int Prop0 { get; set; } } public class BigClass { public int Prop1 { get; set; } public int Prop2 { get; set; } public int Prop3 { get; set; } public int Prop4 { get; set; } public int Prop5 { get; set; } } class Program { const int N = 100000000; static void Main(string[] args) { Stopwatch s; int i; LittleClass lc = new LittleClass(); BigClass bc = new BigClass(); /* ------------------------------------------------------------------*/ s = new Stopwatch(); Console.WriteLine("BigClass test..."); s.Start(); for (i = 0; i < N; i++) { bc = new BigClass(); } s.Stop(); Console.WriteLine("t=" + s.ElapsedMilliseconds.ToString()); /* ------------------------------------------------------------------*/ s = new Stopwatch(); Console.WriteLine("LittleClass test..."); s.Start(); for (i = 0; i < N; i++) { lc = new LittleClass(); } s.Stop(); Console.WriteLine("t=" + s.ElapsedMilliseconds.ToString()); /* ------------------------------------------------------------------*/ Console.ReadKey(); } } } Результат (оптимизация включена) По моим расчетам, время инициализации класса описывается формулой t=(2,6*s+43,8)/(10^7) мс где s - суммарный размер типов всех членов, под которые память выделяется (см.выше), с коэффициентом корелляции 0,99. Наличие постоянной составляющей, я полагаю, объясняется наличие служебной информации, под которую выделяется, предположительно, 16 байт. Исследование проводилось на машине с процессором с тактовой частотой 2.33 ГГц. Для вычисления времени, не зависимого от машины, надо эту формулу умножить на тактовую частоту, получая время в "тактах процессора": t = 0,6*s+10,9

Ответ 2



Поскольку нет инициализации свойств, IL-код будет одинаков и разницы в скорости работы скорее всего не будет. IL для MyClass2: .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 // [46 9 - 46 26] IL_0000: ldarg.0 // this IL_0001: call instance void [mscorlib]System.Object::.ctor() // [49 9 - 49 10] IL_0006: ret } IL для MyClass: .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 // [32 9 - 32 25] IL_0000: ldarg.0 // this IL_0001: call instance void [mscorlib]System.Object::.ctor() // [35 9 - 35 10] IL_0006: ret } // end of method MyClass::.ctor Разница все-таки есть, провел тесты с помощью BenchmarkDotNet. Связано это скорее всего с тем, что для полей автоматических свойств вызывается конструктор по-умолчанию при создании класса. Код программы: using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; namespace ConsoleApp { class Program { static void Main(string[] args) { var summary = BenchmarkRunner.Run(); } } public class ClassCreator { [Benchmark] public MyClass CreateMyClass() { return new MyClass(); } [Benchmark] public MyClass2 CreateMyClass2() { return new MyClass2(); } } public class MyClass { public int Prop { get; set; } } public class MyClass2 { public int Prop1 { get; set; } public int Prop2 { get; set; } public int Prop3 { get; set; } public int Prop4 { get; set; } public int Prop5 { get; set; } } } Результат: BenchmarkDotNet=v0.10.3.0, OS=Microsoft Windows 10.0.14393 Processor=Intel(R) Core(TM) i5-4670 CPU 3.40GHz, ProcessorCount=4 Frequency=3320319 Hz, Resolution=301.1759 ns, Timer=TSC dotnet cli version=1.0.1 [Host] : .NET Core 4.6.25009.03, 64bit RyuJIT DefaultJob : .NET Core 4.6.25009.03, 64bit RyuJIT | Method | Mean | StdDev | |--------------- |---------- |---------- | | CreateMyClass | 2.4932 ns | 0.0185 ns | | CreateMyClass2 | 3.3029 ns | 0.0982 ns |

Комментариев нет:

Отправить комментарий