Вопрос по reflection, .net, c# – Как создать высокопроизводительные классы .NET, используя отражение?

9

Итак, мы все знаем, что Reflecttion во много раз менее эффективен, чем "newing" экземпляр класса, и во многих случаях это просто отлично в зависимости от требований приложения.

QUESTION: How can we create high performance .NET classes using a late binding (Reflection) strategy.

У меня есть существующее требование, которое требует, чтобы экземпляры классов создавались с использованием отражения (CreateInstance), но производительность критична. В моей ситуации я создаю экземпляры для каждого входящего SMS-сообщения в нашем приложении. Во время производства это может быть более миллиона в день.

Я хотел бы услышать и поделиться некоторыми идеями о том, как создавать классы .NET без прямой ссылки на классы в коде, например, используя Reflection. Я также подумал, есть ли способ каким-либо образом кэшировать класс Factory, который может улучшить & quot; Создание & quot; время

Error: User Rate Limit Exceeded Marc Gravell♦
Error: User Rate Limit Exceeded Rex M
Error: User Rate Limit Exceeded Stan R.
Error: User Rate Limit ExceededmuchError: User Rate Limit Exceeded Marc Gravell♦
Error: User Rate Limit Exceeded Rex M

Ваш Ответ

6   ответов
0

Error: User Rate Limit Exceeded

6

Error: User Rate Limit ExceededActivator.CreateInstanceError: User Rate Limit ExceededCreateInstance()Error: User Rate Limit Exceeded

public interface IClassFactory {
    IClass CreateInstance();
}

public interface IClass {
   // your actual class interface.
}

public class DefaultClassFactory : IClassFactory {
    public IClass CreateInstance() {
        return new DefaultClass(); // the implementation class
    }
}

Error: User Rate Limit ExceededstaticError: User Rate Limit ExceededIClassFactoryError: User Rate Limit ExceededDefaultClassFactoryError: User Rate Limit Exceeded

Мое плохое, я прочитал это как представление базового экземпляра, созданного фабрикой, как статического для легкого возврата без создания новых экземпляров нужного класса.
@ Матт сказал, что это статическая фабрика, а не сам класс. Фабрики легко сделать потокобезопасными.
Единственный возможный сбой в этом случае - если приложение является многопоточным, у вас может быть несколько разных вызовов, использующих один и тот же экземпляр, и в итоге получаются экземпляры со смешанным состоянием. Возможно, возвращение клона объекта, если это проблема?
А? Зачем? Фабрика всегда будет создавать новый экземпляр и сама будет поточно-ориентированной, поскольку не имеет внутреннего состояния.
12

Error: User Rate Limit ExceededActivator.CreateInstanceError: User Rate Limit ExceededActivator.CreatInstance(Type)Error: User Rate Limit ExceededTypeError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

  • use generics and the : new() constraint (zero effort)
  • use DynamicMethod and write the IL (not hard)

Error: User Rate Limit ExceedednewError: User Rate Limit Exceeded: new()Error: User Rate Limit ExceededObjectFactory.cs.

Error: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit Exceededil.Emit(OpCodes.Newobj, ...)

@Frank: только если ваш конструктор сам по себе не очень быстр, и в этом случае вас ничто не спасет.new() через общее ограничение приводит к фактическому прямому вызову конструктора, поэтому он не становится быстрее этого.
+1 удобный класс.
@jerry - Мой секундомер говорит мне иначе, извините. Из нововведений генерика я постоянно получаю немного худшую производительность (в 5-8 раз медленнее). Если вы знакомы с ildasm, общий код вызывает Activator.CreateInstance & lt; T & gt ;.
@Frank - если время строительстваthat критический, тогда динамический IL, вероятно, останется вариантом.
новое через общее ограничение не особенно быстро ...
1

Error: User Rate Limit Exceeded

Error: User Rate Limit ExceededAssembly.CreateInstance(typeNameString)Error: User Rate Limit ExceededTypeError: User Rate Limit Exceeded

Error: User Rate Limit ExceededActivator.CreateInstance(type).

Error: User Rate Limit Exceeded

Error: User Rate Limit ExceededEmployeeError: User Rate Limit Exceeded

  • 8 seconds using the new operator

  • 10 seconds using the Factory / Type / Cache approach.

Error: User Rate Limit Exceeded

private IEmployee CachedClassFactory()
{
    if(_typeCache == null)
    {
        // This is a one time hit to load the type into the cache
        string typeName = "ClassFactoryTest.Employee";
        string assemblyName = "ClassFactoryTest";
        Assembly assembly = Assembly.Load(assemblyName);
        IEmployee employee = assembly.CreateInstance(typeName) as IEmployee;                        
        _typeCache = employee.GetType();
    }

    IEmployee instance = Activator.CreateInstance(_typeCache) as IEmployee;

    instance.FirstName = "Raiford";
    instance.LastName = "Brookshire";
    instance.Birthdate = DateTime.Now.AddYears(-35);
    instance.Age = 35;

    return instance;    
}
Не уверен, что вы показываете здесь с точки зрения формулировки, как кэшированное значение будет на 20% медленнее?
Я думаю, что вы можете улучшить это, используя деревья выражений. Смотрите это дляexample.
5

Error: User Rate Limit Exceeded

  • Keep one instance of each class around, once you find you need it. Then, instead of CreateInstance, Clone it.
  • Once you've created the first instance, keep the Type of the instance around. then use Activator.CreateInstance(Type)

Error: User Rate Limit ExceededDictionary<string,Type>Error: User Rate Limit ExceededDictionary<string,object>.

Клонирование быстрее, чем создание экземпляра из кэшированного делегата? Я не думаю, что так, так что лучше было бы кэшировать подрядчик класса? это будет делегат? Если бы отражение использовалось для получения типа, а затем для создания экземпляра, вы получили бы подрядчика из типа или экземпляра. Можно добавить пример кода. Насколько я понимаю, кэширование ctor типов в словаре будет самым быстрым.
5

Error: User Rate Limit ExceededError: User Rate Limit Exceeded

Похожие вопросы