So there's a number of well-known performance issues with .NET. Reflection is slow. Throwing exceptions takes half a second. Cold starts take forever, the memory footprint is high. Half these performance bugs people just take for granted, "Oh yeah
don't use reflection a lot, its pretty slow". But WHY is reflection slow? Why doesn't someone at MS open a bug against .NET, "Priority 1, fix NOW, millions of customers experiencing millions of dollars lost in operating costs cause of a slow reflection code,
blah blah"
Environments like .NET are supposedly awesome because if you make performance improvements to the runtime, the JIT compiler, etc., every single program that targets .NET receives a performance benefit. And today that is A LOT of programs. But the thing is,
they DON'T update the runtime. They haven't touched it in years, and 2.0 didn't do much for performance anyway. And it's not like you can't make runtime changes without breaking compatibility. You don't have to touch the libraries, just make the compiler
faster.
And now MS is investing big in Silverlight and its "thinner" runtime, so .NET will probably never see any improvements beyond new really fat libraries like WPF.
-
-
DigitalDud wrote:So there's a number of well-known performance issues with .NET. Reflection is slow. Throwing exceptions takes half a second. Cold starts take forever, the memory footprint is high. Half these performance bugs people just take for granted, "Oh yeah don't use reflection a lot, its pretty slow". But WHY is reflection slow? Why doesn't someone at MS open a bug against .NET, "Priority 1, fix NOW, millions of customers experiencing millions of dollars lost in operating costs cause of a slow reflection code, blah blah"
Well with the things you mentioned it's likely not to be performance issues. Its simply design issues. And as you wrote these have been VERY well documented and are widely known. If you have Exceptions in your normal execution path its simply plain wrong.
Moreover as these were design choices they are
a) likely to not be correctable without changing the design
b) speeding them up would not help anybody, because nobody uses these constructs in performance-critical code anyways.
DigitalDud wrote:
Environments like .NET are supposedly awesome because if you make performance improvements to the runtime, the JIT compiler, etc., every single program that targets .NET receives a performance benefit. And today that is A LOT of programs. But the thing is, they DON'T update the runtime. They haven't touched it in years, and 2.0 didn't do much for performance anyway. And it's not like you can't make runtime changes without breaking compatibility. You don't have to touch the libraries, just make the compiler faster.
I'm here with you for this one (mostly). Obviously not the compiler, but the JIT-results, but I guess thats what you meant anyways.
E.g. why do NGEN compiled programs usually still perform worse that the same application compiled with an optimizing c++ compiler?
With the additionaly system information that NGEN has (Exact processor type, available RAM, ...). It should always be able to outperform or at least be on line with precompilers.
And the JIT still isn't able to take advantage from its special execution semantics to dynamically optimize applications (e.g. like HotSpot). -
Reflection is slow? I've just written an app that uses reflection quite a lot, and its far from slow.. reflection might not be as performant as normal code but its far from slow..
-
stevo_ wrote:Reflection is slow? I've just written an app that uses reflection quite a lot, and its far from slow.. reflection might not be as performant as normal code but its far from slow..
The time taken to execute a method using reflection compared to directly executing the method is much longer... reflection is slow compared to directly accessing methods, properties, classes etc.
-
So why's reflection slow: It has to lookup the metadata of the application before it can invoke the method. That's perfectly normal and after that it executes normally.
I've used .NET since the first beta of version 1.0 and I never experienced unmanagably slow applications with it. The key here is that you need to be very aware of how the garbage collector and the other mechanics work.
Java has the same issues, especially with the swing GUI library. Of cource C++ is faster, but it has the other downsides as well, like a lack of checks on the boundaries of buffers and memory management that doesn't protect against memory leaks. -
stevo_ wrote:Reflection is slow? I've just written an app that uses reflection quite a lot, and its far from slow.. reflection might not be as performant as normal code but its far from slow..
Depends on what you're doing. A few reflection calls won't make a different, but do it millions of times in a tight loop and you'll feel it.
Reflection is not just slower, it's orders of magnitude slower than a regular method call. This is perfectly normal because of the extra work it has to do. If you're really worried about it, use a dynamic method. -
WillemM wrote:So why's reflection slow: It has to lookup the metadata of the application before it can invoke the method. That's perfectly normal and after that it executes normally.
Exactly, people are just taking this for granted. How is "looking up metadata in order to invoke a method" any different from doing a virtual call by looking up a vtable? Just because the design is inherently slow doesn't mean it's not a bug. -
For the record, I said I reflection wasn't slow.. slow suggests its a real sacrifice to use.
I don't think many systems using reflection are going to be calling reflection based methods millions of times recursively..
Edit: the dynamic method is an interesting class.. -
I agree with the original poster. None of these things need to be this way. Just look at other languages/virtual machines where overhead was considered more carefully during design. You can see examples where startup is fast, reflection is fast, basic memory overhead is minimal. From what I can tell it is a general reflection of a "code and move on" style of development, continual planned obsolecence.
-
DigitalDud wrote:How is "looking up metadata in order to invoke a method" any different from doing a virtual call by looking up a vtable?
Because the vtable's layout is determined by the compiler. If you make a virtual call, the compiler will translate the method name into an index in the vtable. So at runtime, it's just a direct index.
With reflection, the type information must be loaded. The list of methods must be searched for one with a matching name for the one requested (string comparisons, which is slow). It has to check the type of the arguments (again something which the compiler normally does). Only then can it call the method. -
Sven Groot wrote:
Depends on what you're doing. A few reflection calls won't make a different, but do it millions of times in a tight loop and you'll feel it.
Reflection is not just slower, it's orders of magnitude slower than a regular method call. This is perfectly normal because of the extra work it has to do. If you're really worried about it, use a dynamic method.
Wow, talk about obfusticated.
Anyway, I thought you might be interested in the results from VB.NET, slightly revised, and including VB's late-binding abilities.
NOT optimised, and may have errors.
DEBUG:
Each test will perform 1000000 iterations.
Compiled 00:00:00.3801251
Dynamic Method 00:00:00.3956237
Reflection 1 00:00:10.0621492
Reflection 2 00:00:12.1479894
Late Binding 00:00:22.9242498
RELEASE:
Each test will perform 1000000 iterations.
Compiled 00:00:00.3749116
Dynamic Method 00:00:00.3929541
Reflection 1 00:00:08.9885750
Reflection 2 00:00:10.8800976
Late Binding 00:00:21.4694188
The source (Console):
Imports System
Imports System.Diagnostics
Imports System.Reflection
Imports System.Reflection.Emit
Class Foo
Private _bar As String
Public Property Bar() As String
Get
Return _bar
End Get
Set(ByVal value As String)
_bar = value
End Set
End Property
End Class
Module Module1
Public Const kITER = 1000000
Delegate Sub TestDelegate(ByVal arg As Foo, ByVal str As String)
Function CreateMethod() As TestDelegate
Dim args() As Type = {GetType(Foo), GetType(String)}
Dim method As New DynamicMethod("Test", Nothing, args, GetType(Module1))
Dim gen As ILGenerator = method.GetILGenerator()
gen.Emit(OpCodes.Ldarg_0)
gen.Emit(OpCodes.Ldarg_1)
Dim m As MethodInfo = GetType(Foo).GetProperty("Bar").GetSetMethod()
gen.EmitCall(OpCodes.Call, m, Nothing)
gen.Emit(OpCodes.Ret)
Return method.CreateDelegate(GetType(TestDelegate))
End Function
Sub Main()
Dim i As Integer
Dim f As New Foo
Dim w As New Stopwatch
Console.WriteLine("Each test will perform {0} iterations." & vbCrLf, kITER)
Console.Write("Compiled" & vbTab)
w.Start()
For i = 1 To kITER
f.Bar = i.ToString()
Next
w.Stop()
Console.WriteLine(w.Elapsed)
Console.Write("Dynamic Method" & vbTab)
Dim test As TestDelegate = CreateMethod()
w.Reset()
w.Start()
For i = 1 To kITER
test(f, i.ToString())
Next
w.Stop()
Console.WriteLine(w.Elapsed)
Console.Write("Reflection 1" & vbTab)
w.Reset()
w.Start()
Dim t As Type = f.GetType()
Dim pi As PropertyInfo = t.GetProperty("Bar")
For i = 1 To kITER
pi.SetValue(f, i.ToString(), Nothing)
Next
w.Stop()
Console.WriteLine(w.Elapsed)
Console.Write("Reflection 2" & vbTab)
w.Reset()
w.Start()
For i = 1 To kITER
Dim t2 As Type = f.GetType()
Dim pi2 As PropertyInfo = t2.GetProperty("Bar")
pi2.SetValue(f, i.ToString(), Nothing)
Next
w.Stop()
Console.WriteLine(w.Elapsed)
Console.Write("Late Binding" & vbTab)
Dim o As Object = f
w.Reset()
w.Start()
For i = 1 To kITER
o.Bar = i.ToString()
Next
w.Stop()
Console.WriteLine(w.Elapsed)
Console.Write(vbCrLf & "Done. Press a key")
Console.ReadKey()
End Sub
End Module -
Sven Groot wrote:If you're really worried about it, use a dynamic method.
Interesting. Do you have any good references for learning IL op codes? -
Sven Groot wrote:Reflection is not just slower, it's orders of magnitude slower than a regular method call. This is perfectly normal because of the extra work it has to do. If you're really worried about it, use a dynamic method.
I know that this is an old thread drudged up by that weird Bill Gates groupie, but I hadn't read this post in the past, and this DynamicMethod thing looks really interesting. On the other hand, I may just use something like IronPython (or IronRuby or even VBX someday) if my code requirements are that dynamic, because DynamicMethod generation code smells.
-
kachchhu wrote:
hello, i want know about only bill gates if you are american so that help me & give me conectivity of bill gates.....................................kachchhu fr:uk
big_g@nevergonnahappen.com -
try
{
Slow and dirty methods of doing things are slow and dirty. News at 11.
}
catch(Flame flame)
{
Use structured exception handling and reflection in your code only where absolutely necessary.
}
-
ManipUni wrote:
catch(Flame flame)
{
Use structured exception handling and reflection in your code only where absolutely necessary.
}
And always forget the naming guidelines and call your exceptions exampleException
-
blowdart wrote:

ManipUni wrote:
catch(Flame flame)
{
Use structured exception handling and reflection in your code only where absolutely necessary.
}
And always forget the naming guidelines and call your exceptions exampleException
That's one of the few things I don't like with many OOP languages: is that certain types of a BCL are integral to features of a language.
The normal types, I can understand: Intxx, String, Object, Array... but "Exception" is too special to be a class in a BCL.
How do other languages solve this problem?
-
W3bbo wrote:
The normal types, I can understand: Intxx, String, Object, Array... but "Exception" is too special to be a class in a BCL.
How do other languages solve this problem?
Why special? It's part of the error handling approach, so it belongs in there. What's your thinking behind this?
Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.