На данный вопрос уже ответили:
Способы создания объектов в C#
2 ответа
Для приведения типов наследуемого объекта написана функция. Есть-ли какая-либо возможность создать объект нужного типа без использования класса Activator?
public T ToObject
Ответ
Я написал простой тест для BenchmarkDotNet
[MemoryDiagnoser]
public class Creator
{
public class A { }
[Benchmark]
public A ExplicitCtor()
{
return new A();
}
[Benchmark]
public A WithActivator()
{
return Activator.CreateInstance();
}
[Benchmark]
public A WithReflection()
{
return (A)typeof(A).GetConstructor(new Type[0]).Invoke(new object[0]);
}
ConstructorInfo ctor;
[Benchmark]
public A WithReflectionCached()
{
if (ctor == null) ctor = typeof(A).GetConstructor(new Type[0]);
return (A)ctor.Invoke(new object[0]);
}
Func lambda;
[Benchmark]
public A WithLambla()
{
if (lambda == null)
lambda = Expression.Lambda
[Benchmark]
public A WithCustomActivator()
{
return CustomActivator.CreateInstance();
}
}
(CustomActivator by Sergey Teplyakov можно взять здесь)
Результаты получились следующие:
| Method | Mean | Error | StdDev | Median | Gen 0 | Allocated |
|--------------------- |-----------:|----------:|----------:|-----------:|-------:|----------:|
| ExplicitCtor | 2.591 ns | 0.0523 ns | 0.0489 ns | 2.582 ns | 0.0076 | 12 B |
| WithActivator | 113.661 ns | 0.4652 ns | 0.3885 ns | 113.583 ns | 0.0074 | 12 B |
| WithReflection | 369.719 ns | 6.9477 ns | 5.4243 ns | 367.856 ns | 0.0229 | 36 B |
| WithReflectionCached | 281.290 ns | 0.9358 ns | 0.7814 ns | 281.415 ns | 0.0148 | 24 B |
| WithLambla | 17.391 ns | 0.0700 ns | 0.0621 ns | 17.373 ns | 0.0076 | 12 B |
| WithCustomActivator | 27.644 ns | 0.6665 ns | 1.3155 ns | 27.039 ns | 0.0076 | 12 B |
Т.е. что мы видим: рефлексия очень медленная и даже кеширование конструктора не сильно помогает, создание объекта с помощью Activator быстрее явной рефлексии в 2,5-3 раза, но всё еще сильно медленнее явного вызова конструктора (в 40 раз!), наиболее эффективный метод, как и ожидалось — создание и кеширование делегата, создающего объекты, он всего в ~6 раз медленнее явного вызова конструктора (тут, подозреваю, медленное именно создание делегата, а сам его вызов не должен уступать явному вызову конструктора, т.е. чем больше объектов мы будем создавать, тем ближе будет средняя скорость к идеальной).
Таким образом, имеет смысл переписать ваш метод во что-то вроде такого:
Dictionary
Комментариев нет:
Отправить комментарий