static void Main() { Assembly assembly = CSScript.LoadCode( @"using System; public class Calculator : ICalculator { public int Add(int a, int b) { return a + b; } public string Join(string a, string b) { return a + b; } }"); AsmHelper calc = new AsmHelper(assembly); object instance = calc.CreateObject("Calculator"); //calc.CreateObject("*") can be used too if assembly has only one class defined FastInvokeDelegate methodInvoker = calc.GetMethodInvoker("Calculator.Add", 0, 0); int numOfLoops = 1000000; TestReflection(numOfLoops, calc, instance); TestFastInvoking(numOfLoops, calc, instance); TestDelegates(numOfLoops, methodInvoker, instance); TestInterface(numOfLoops, instance); TestInterfaceAlignment(numOfLoops, instance); TestDynamic(numOfLoops, instance); TestCompiledCode(numOfLoops); TestCompiledDelegate(numOfLoops); //TestMethodDelegates(); }
static void TypeSafeDelegate(AsmHelper script, object instance) { FastInvokeDelegate sumInvoker = script.GetMethodInvoker("Claculator.Sum", 0, 0); //type unsafe delegate Action <int, int> Sum = delegate(int a, int b) { sumInvoker(instance, a, b); }; //type safe delegate Sum(1, 2); Sum(4, 7); }
static void TypeUnSafeDelegate(AsmHelper script, object instance) { FastInvokeDelegate Sum = script.GetMethodInvoker("Claculator.Sum", 0, 0); //streakly speaking the following calls are type safe but they are not subject of //arguments checking Sum(instance, 1, 2); Sum(instance, 4, 7); //incorrect number of arguments //Sum(instance, 4, 7, 9); //runtime - OK, compiletime - OK //Sum(instance, 4); //runtime - Error, compiletime - OK }
static void TestDelegates(int numOfLoops, FastInvokeDelegate fastInvoker, object instance) { //Starting from version v2.2 AsmHelper can return dynamically emitted method //invoker (delegate) which can be used by the host application to invoke script methods without AsmHelper. // //This option allows script methods execution more than 250 times faster in than in pure reflection calls //available in AsmHelper v2.1. The generated FastInvokeDelegate is almost as fast as direct calls for statically compiled types. Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < numOfLoops; i++) { fastInvoker(instance, 1, 2); } sw.Stop(); Console.WriteLine("Delegate: " + sw.ElapsedMilliseconds); }
/// <summary> /// Default constructor /// </summary> /// <param name="parentClass">An instance of the class that the API /// call is contained in, or null if the API call is a static method</param> /// <param name="methodInfo">A reference to type information for the /// API call</param> public ApiMethod(object parentClass, MethodInfo methodInfo) { ParentClass = parentClass; MethodInfo = methodInfo; Invoker = FastInvoke.Create(methodInfo); }
static void TestDelegates(int numOfLoops, FastInvokeDelegate fastInvoker, object instance) { //Starting from version v2.2 AsmHelper can return dynamically emitted method //invoker (delegate) which can be used by the host application to invoke script methods without AsmHelper. // //This option allows script methods execution more than 250 times faster in than in pure reflection calls //available in AsmHelper v2.1. The generated FastInvokeDelegate is almost as fast as direct calls for statically compiled types. Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < numOfLoops; i++) fastInvoker(instance, 1, 2); sw.Stop(); Console.WriteLine("Delegate: " + sw.ElapsedMilliseconds); }
/// <summary> /// Default constructor /// </summary> /// <param name="parent">An instance of the API class containing this /// method, or null if the API call is a static method</param> /// <param name="methodInfo">A reference to type information for the /// API call</param> public ApiMethod(IScriptApi parent, MethodInfo methodInfo) { Parent = parent; MethodInfo = methodInfo; Invoker = FastInvoke.Create(methodInfo); }