Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Precompile C# method before executing

I measure code speed like this:

var sw = new Stopwatch();
sw.Start();
DoSomething();
sw.Stop();
AddLog("Method speed is (ms): "+sw.ElapsedMilliseconds);

But first call of DoSomething() is slow, because code is compiling. Workaround is measure speed of second call like this:

var sw = new Stopwatch();
DoSomething();
sw.Start();
DoSomething();
sw.Stop();
AddLog("Method speed is (ms): "+sw.ElapsedMilliseconds);

Is there way to precompile DoSomethig() without first call?

like image 454
FireShock Avatar asked Jul 25 '14 05:07

FireShock


1 Answers

The documentation does not unequivocally state so, but according to this article (among others) you can use the RuntimeHelpers.PrepareMethod to precompile a method.

To elaborate on my comment (aforementioned) here is a code sample:

static void WarmUp()
{
    var handle = typeof (Program).GetMethod("DoSomething").MethodHandle;
    RuntimeHelpers.PrepareMethod(handle);
}

Update

Here is a more generic (although somewhat-brittle) solution that will account for instance members too:

public static class MethodWarmerUper
{
    public static void WarmUp(string methodName)
    {
        var handle = FindMethodWithName(methodName).MethodHandle;
        RuntimeHelpers.PrepareMethod(handle);
    }

    private static MethodInfo FindMethodWithName(string methodName)
    {
        return 
            Assembly.GetExecutingAssembly()
                    .GetTypes()
                    .SelectMany(type => type.GetMethods(MethodBindingFlags))
                    .FirstOrDefault(method => method.Name == methodName);
    }

    private const BindingFlags MethodBindingFlags =
        BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic |
        BindingFlags.Instance | BindingFlags.Static;
}
like image 71
User 12345678 Avatar answered Oct 07 '22 22:10

User 12345678