Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Recently I asked an almost identical question:</p> <p><a href="https://stackoverflow.com/questions/5053032/performance-of-compiled-to-delegate-expression">Performance of compiled-to-delegate Expression</a></p> <p>The solution for me was that I shouldn't call <code>Compile</code> on the <code>Expression</code>, but that I should call <code>CompileToMethod</code> on it and compile the <code>Expression</code> to a <code>static</code> method in a dynamic assembly. </p> <p>Like so:</p> <pre><code>var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( new AssemblyName("MyAssembly_" + Guid.NewGuid().ToString("N")), AssemblyBuilderAccess.Run); var moduleBuilder = assemblyBuilder.DefineDynamicModule("Module"); var typeBuilder = moduleBuilder.DefineType("MyType_" + Guid.NewGuid().ToString("N"), TypeAttributes.Public)); var methodBuilder = typeBuilder.DefineMethod("MyMethod", MethodAttributes.Public | MethodAttributes.Static); expression.CompileToMethod(methodBuilder); var resultingType = typeBuilder.CreateType(); var function = Delegate.CreateDelegate(expression.Type, resultingType.GetMethod("MyMethod")); </code></pre> <p>It's not ideal however. I'm not quite certain to which types this applies exactly, but I think that types that are taken as parameters by the delegate, or returned by the delegate <em>have</em> to be <code>public</code> and non-generic. It has to be non-generic because generic types apparently access <code>System.__Canon</code> which is an internal type used by .NET under the hood for generic types and this violates the "has to be a <code>public</code> type rule).</p> <p>For those types, you can use the apparently slower <code>Compile</code>. I detect them in the following way:</p> <pre><code>private static bool IsPublicType(Type t) { if ((!t.IsPublic &amp;&amp; !t.IsNestedPublic) || t.IsGenericType) { return false; } int lastIndex = t.FullName.LastIndexOf('+'); if (lastIndex &gt; 0) { var containgTypeName = t.FullName.Substring(0, lastIndex); var containingType = Type.GetType(containgTypeName + "," + t.Assembly); if (containingType != null) { return containingType.IsPublic; } return false; } else { return t.IsPublic; } } </code></pre> <p>But like I said, this isn't ideal and I would still like to know why compiling a method to a dynamic assembly is <em>sometimes</em> an order of magnitude faster. And I say sometimes because I've also seen cases where an <code>Expression</code> compiled with <code>Compile</code> is just as fast as a normal method. See my question for that. </p> <p>Or if someone knows a way to bypass the "no non-<code>public</code> types" constraint with the dynamic assembly, that's welcome as well.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload