Closed NikolayPianikov closed 6 years ago
Half (or may be more) of container usage cases is integration within other tools, frameworks. Usually it is done by implementing some kind of IResolver
interface. The IResolver
need to operate with types known at run-time, returning the object
and IEnumerable<object>
.
I would say that statically known resolved type T
is more specialized case than more general run-time object
.
Consider this issue, it may interesting to know the performance of Resolve<T>
, but rather side by side with Resolve(Type t)
instead of replacing it.
This is my IMHO though and up for @danielpalme to decide.
@dadhi
Correct, and if I remember correctly, then this pull request changed the generic version to the Resolve(Type t)
approach:
https://github.com/danielpalme/IocPerformance/pull/8
Yes I measured that the performance of <T>
better then object
(rate ~ 3). That is the test:
class Program
{
static void Main(string[] args)
{
var count = 10000000;
MyClass value = new MyClass();
value = (MyClass)Get(value);
value = Get<MyClass>(value);
var stopwatch1 = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
value = (MyClass)Get(value);
}
stopwatch1.Stop();
var stopwatch2 = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
value = Get<MyClass>(value);
}
stopwatch2.Stop();
Console.WriteLine($"{stopwatch1.ElapsedMilliseconds} / {stopwatch2.ElapsedMilliseconds}");
Console.ReadLine();
}
class MyClass
{
}
static T Get<T>(T value)
{
return value;
}
static object Get(MyClass myClass)
{
return myClass;
}
}
For object
we have:
IL_002a: ldloc.1 // 'value'
IL_002b: call object ConsoleApp1.Program::Get(class ConsoleApp1.Program/MyClass)
IL_0030: castclass ConsoleApp1.Program/MyClass
IL_0035: stloc.1 // 'value'
For <T>
we have:
IL_0052: ldloc.1 // 'value'
IL_0053: call !!0/*class ConsoleApp1.Program/MyClass*/ ConsoleApp1.Program::Get<class ConsoleApp1.Program/MyClass>(!!0/*class ConsoleApp1.Program/MyClass*/)
IL_0058: stloc.1 // 'value'
The bodies of methods are the same:
IL_0000: ldarg.0 // 'value'
IL_0001: ret
And wach IoC in the test has own `Resolve
Another 2 points:
container.Resolve()
is not common way how users use IoC containers. For example it could be just one call container.Resolve()
of some root object and in others cases it just some injection without any container.Resolve()
.
No IoC
case uses Dictionary and lamdas. I think No IoC
should be just like new Class1(new Class2())
ans so on. That would be the true test
@NikolayPianikov Resolve(Type)
is how it's used when integrating with frameworks like asp.net and many other framework so for a lot containers Resolve(Type)
is a huge use case and Resolve<T>
is not used much.
I agree with @dadhi an additional Resolve<T>
test might be interesting if you resolved the exact same types so you could do an apples to apples comparison to Resolve(Type)
.
Well, I agree with the majority. And it is a too small loss of performance. I had a slightly different experience using IoC :) I close the question
It makes results more accurate because of there are no any additional operations of conversions of type. Actually it is more sensible scenario to use these methods and all IoC containers have these methods