Let us consider a scenario where you catch some exception and in the exception handler do some costly operation. You can write that code in either of the following ways
Method-1 : Separate method call
public class Program
{
public static void Main(string[] args)
{
try
{
using (DataStore ds = new DataStore())
{
// ...
}
}
catch (Exception ex)
{
ErrorReporter(ex);
}
}
private static void ErrorReporter(Exception ex)
{
string path = System.IO.Path.GetTempFileName();
ErrorDumper ed = new ErrorDumper(path, ex);
ed.WriteError();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(path);
RemoteErrorReporter er = new RemoteErrorReporter(xmlDoc);
er.ReportError();
}
}
-
Method-2 : Inline
public static void Main(string[] args)
{
try
{
using (DataStore ds = new DataStore())
{
// ...
}
}
catch (Exception ex)
{
string path = System.IO.Path.GetTempFileName();
ErrorDumper ed = new ErrorDumper(path, ex);
ed.WriteError();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(path);
RemoteErrorReporter er = new RemoteErrorReporter(xmlDoc);
er.ReportError();
}
}
-
The simple difference is that in the first case the exception handler is written as a separate method and in the second case it is placed directly inline inside the handler itself.
The question is which is better in terms of performance?
In case you do have significant code and type reference in the handler and you expect the exception to be thrown rarely in an application execution then the Method-1 is going to be more performant.
The reason is that just before executing a method the whole method gets jitted. The jitted code contains stubs to the other method's it will call but it doesn't do a recursive jitting. This means when Main gets called it gets jitted but the method ErrorReporter is still not jitted. So in case the exception is never fired all the code inside ErrorReporter never gets Jitted. This might prove to be significant saving in terms of time and space if the handling code is complex and refers to type not already referenced.
However, if the code is inline then the moment Main gets jitted all the code inside the catch block gets jitted. This is expensive not only because it leads to Jitting of code that is never executed but also because all types referenced in the catch block is also resolved resulting in loading a bunch of dlls after searching though the disk. In our example above System.Xml.dll and the other dll containing remote error reporting gets loaded even though they will never be used. Since disk access, loading assemblies and type resolution are slow, the simple change can prove to give some saving.
No comments:
Post a Comment