Skip to content

Instantly share code, notes, and snippets.

@fearofcode
Last active November 4, 2019 08:10
Show Gist options
  • Save fearofcode/b6b954ea99abe7193a24b322f441950f to your computer and use it in GitHub Desktop.
Save fearofcode/b6b954ea99abe7193a24b322f441950f to your computer and use it in GitHub Desktop.
Simple example of dynamically compiled code that can access data in the program that compiles the assembly
using System;
using System.Diagnostics;
using System.Linq;
namespace csharpdynamiccompilationtest
{
public class RegularClass
{
public static int Get(int[] i) { return i.Sum() + Program.rng.Next(1, 5); }
}
public class Program
{
public static Random rng = new Random();
public static int k = 5;
static void Main(string[] args)
{
var refs = AppDomain.CurrentDomain.GetAssemblies();
var refFiles = refs.Where(a => !a.IsDynamic).Select(a => a.Location).ToArray();
var cSharp = new Microsoft.CSharp.CSharpCodeProvider();
var compileParams = new System.CodeDom.Compiler.CompilerParameters(refFiles)
{
GenerateInMemory = true,
GenerateExecutable = false
};
string code = "using System; using System.Linq; namespace csharpdynamiccompilationtest { public class DynamicClass { public static int Get(int[] i ) { return i.Sum() + Program.rng.Next(1, 5); }} } ";
string className = "csharpdynamiccompilationtest.DynamicClass";
var compilerResult = cSharp.CompileAssemblyFromSource(compileParams, code);
if (compilerResult.Errors.HasErrors)
{
foreach (var error in compilerResult.Errors)
{
Console.WriteLine(error);
}
Console.ReadLine();
return;
}
var asm = compilerResult.CompiledAssembly;
var tempType = asm.GetType(className);
var method = tempType.GetMethod("Get");
Stopwatch stopWatch = new Stopwatch();
long resolution = 1000000000 / Stopwatch.Frequency;
Console.WriteLine("The minimum measurable time on this system is: {0} nanoseconds", resolution);
var id = 0;
int[] ints = new int[10000];
for(int i = 0; i < 10000; i++)
{
ints[i] = rng.Next(1, 100);
}
stopWatch.Start();
id += (int)method.Invoke(null, new object[1] { ints });
stopWatch.Stop();
Console.WriteLine("value returned: {0}", id);
long nanoseconds = resolution * stopWatch.ElapsedTicks;
Console.WriteLine("first invocation: {0} nanoseconds", nanoseconds);
stopWatch = new Stopwatch();
id = 0;
stopWatch.Start();
id += (int)method.Invoke(null, new object[1] { ints });
stopWatch.Stop();
Console.WriteLine("value returned: {0}", id);
nanoseconds = resolution * stopWatch.ElapsedTicks;
Console.WriteLine("second invocation: {0} nanoseconds", nanoseconds);
id = 0;
stopWatch = new Stopwatch();
stopWatch.Start();
id += RegularClass.Get(ints);
stopWatch.Stop();
Console.WriteLine("value returned from RegularClass: {0}", id);
nanoseconds = resolution * stopWatch.ElapsedTicks;
Console.WriteLine("first RegularClass invocation: {0} nanoseconds", nanoseconds);
id = 0;
stopWatch = new Stopwatch();
stopWatch.Start();
id += RegularClass.Get(ints);
stopWatch.Stop();
Console.WriteLine("value returned from RegularClass: {0}", id);
nanoseconds = resolution * stopWatch.ElapsedTicks;
Console.WriteLine("second RegularClass invocation: {0} nanoseconds", nanoseconds);
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment