Comments 8
А почему решили писать свой контейнер? Чем не подошли существующие?
Долгое время для меня всё, что происходит внутри контейнеров оставалось загадкой, поэтому решил разобраться с этим попытавшись написать своё собственное решение. Это побудило меня к длительному изучению внутреннего устройства существующих контейнеров (Unity, Ninject, StructureMap) и развеяло всё мистическое :)
Я правильно понимаю, что автор берет массив длины около миллиона, а потом примерно миллион раз ищет в нем элемент?
Глубоко код не смотрел, но прямо навскидку попалась пара подозрительных вещей:
1. BindingResolver: вы используете
2. DisposeManager: почему
Если я все правильно понял и если в остальном коде это продолжается, то понятно, почему разница с тем же LightInject больше, чем в 30 раз. Стоит более детально разобраться в структурах данных.
1. BindingResolver: вы используете
ConcurrentDictionary
, но обращаетесь к нему всегда изнутри locked-блока — в чем смысл?2. DisposeManager: почему
List
, а не HashSet
или Dictionary
? На большом количестве объектов стоимость вставки и поиска гораздо ниже.Если я все правильно понял и если в остальном коде это продолжается, то понятно, почему разница с тем же LightInject больше, чем в 30 раз. Стоит более детально разобраться в структурах данных.
Да, вы правы. Что-то подсмотрел у других контейнеров, что-то сам не совсем оптимально реализовал. Буду разбираться.
1. Замена ConcurrentDictionary на обычный Dictionary привнесла порядка 5% ускорения;
2. Возможно, но в данном случае роли не играет, т.к. объекты не IDisposable;
2. Возможно, но в данном случае роли не играет, т.к. объекты не IDisposable;
Если я не ошибаюсь, в LightInject функция activator'a (или даже весь Resolve) собирается посредством emit'a IL инструкций. На мой взгляд, это первостепенная причина такого разрыва.
Sign up to leave a comment.
История оптимизации одного IoC контейнера