123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- using System.Reflection;
- using BenchmarkDotNet.Attributes;
- using Jint.Native;
- using Jint.Native.Array;
- namespace Jint.Benchmark;
- [MemoryDiagnoser]
- public class InteropBenchmark
- {
- private const int OperationsPerInvoke = 1_000;
- public class Person
- {
- public string Name { get; set; }
- public int Age { get; set; }
- }
- private Engine _engine;
- [GlobalSetup]
- public void Setup()
- {
- _engine = new Engine(cfg => cfg.AllowClr(
- typeof(Person).GetTypeInfo().Assembly,
- typeof(Console).GetTypeInfo().Assembly,
- typeof(System.IO.File).GetTypeInfo().Assembly))
- .SetValue("log", new Action<object>(Console.WriteLine))
- .SetValue("assert", new Action<bool>(x => { }))
- .SetValue("equal", new Action<object, object>((x, y) => { }));
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void DelegatesCanBeSet()
- {
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("square", new Func<double, double>(x => x * x));
- _engine.Execute("assert(square(10) === 100);");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void ExtraParametersAreIgnored()
- {
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("passNumber", new Func<int, int>(x => x));
- _engine.Execute("assert(passNumber(123,'test',{},[],null) === 123);");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void GetObjectProperties()
- {
- var p = new Person
- {
- Name = "Mickey Mouse"
- };
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("p", p);
- _engine.Execute("assert(p.Name === 'Mickey Mouse');");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void InvokeObjectMethods()
- {
- var p = new Person
- {
- Name = "Mickey Mouse"
- };
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("p", p);
- _engine.Execute(@"assert(p.ToString() === 'Mickey Mouse');");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void SetObjectProperties()
- {
- var p = new Person
- {
- Name = "Mickey Mouse"
- };
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("p", p);
- _engine.Execute("p.Name = 'Donald Duck'; assert(p.Name === 'Donald Duck');");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void GetIndexUsingStringKey()
- {
- var dictionary = new Dictionary<string, Person>();
- dictionary.Add("person1", new Person {Name = "Mickey Mouse"});
- dictionary.Add("person2", new Person {Name = "Goofy"});
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("dictionary", dictionary);
- _engine.Execute("assert(dictionary['person1'].Name === 'Mickey Mouse'); assert(dictionary['person2'].Name === 'Goofy');");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void GenericMethods()
- {
- var dictionary = new Dictionary<int, string>
- {
- {1, "Mickey Mouse"}
- };
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("dictionary", dictionary);
- _engine.Execute("dictionary.Clear(); dictionary.Add(2, 'Goofy'); assert(dictionary[2] === 'Goofy');");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void MultiGenericTypes()
- {
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.Execute(@"
- var type = System.Collections.Generic.Dictionary(System.Int32, System.String);
- var dictionary = new type();
- dictionary.Add(1, 'Mickey Mouse');
- dictionary.Add(2, 'Goofy');
- assert(dictionary[2] === 'Goofy');
- ");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void IndexOnList()
- {
- var list = new List<object>(2);
- list.Add("Mickey Mouse");
- list.Add("Goofy");
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("list", list);
- _engine.Execute("list[1] = 'Donald Duck'; assert(list[1] === 'Donald Duck');");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void EcmaValuesAreAutomaticallyConvertedWhenSetInPoco()
- {
- var p = new Person
- {
- Name = "foo",
- };
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("p", p);
- _engine.Execute(@"
- assert(p.Name === 'foo');
- assert(p.Age === 0);
- p.Name = 'bar';
- p.Age = 10;
- ");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void Trim()
- {
- var p = new Person
- {
- Name = "Mickey Mouse "
- };
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("p", p);
- _engine.Execute(@"
- assert(p.Name === 'Mickey Mouse ');
- p.Name = p.Name.trim();
- assert(p.Name === 'Mickey Mouse');
- ");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void MathFloor()
- {
- var p = new Person();
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("p", p);
- _engine.Execute("p.Age = Math.floor(1.6); assert(p.Age === 1);");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void DelegateAsFunction()
- {
- var even = new Func<int, bool>(x => x % 2 == 0);
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("even", even);
- _engine.Execute("assert(even(2) === true);");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void ConvertArrayToArrayInstance()
- {
- var ints = new[] {1, 2, 3, 4, 5, 6};
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine
- .SetValue("values", ints)
- .Execute("values.filter(function(x){ return x % 2 == 0; })");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void ConvertListsToArrayInstance()
- {
- var ints = new List<object> {1, 2, 3, 4, 5, 6};
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine
- .SetValue("values", ints)
- .Execute("new Array(values).filter(function(x){ return x % 2 == 0; })");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void ConvertArrayInstanceToArray()
- {
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.Execute("'[email protected]'.split('@');");
- }
- }
-
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void ResolvingConsoleWriteLine()
- {
- var originalOut = Console.Out;
- Console.SetOut(TextWriter.Null);
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.Execute("System.Console.WriteLine('value to write');");
- }
- Console.SetOut(originalOut);
- }
-
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void Setter()
- {
- var p = new Person();
- _engine.SetValue("p", p);
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.Execute("p.Age = 42;");
- }
- }
- [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
- public void LoopWithNativeEnumerator()
- {
- JsValue Adder(JsValue argValue)
- {
- ArrayInstance args = argValue.AsArray();
- double sum = 0;
- foreach (var item in args)
- {
- if (item.IsNumber())
- {
- sum += item.AsNumber();
- }
- }
- return sum;
- }
- for (int i = 0; i < OperationsPerInvoke; ++i)
- {
- _engine.SetValue("getSum", new Func<JsValue, JsValue>(Adder));
- _engine.Execute("getSum([1,2,3]);");
- }
- }
- }
|