Skip to content

Commit 694d2eb

Browse files
committed
Added a benchmarks
1 parent 19a85f3 commit 694d2eb

File tree

7 files changed

+1049
-1
lines changed

7 files changed

+1049
-1
lines changed

MsieJavaScriptEngine.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SharedFiles", "SharedFiles"
1818
EndProject
1919
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MsieJavaScriptEngine", "src\MsieJavaScriptEngine\MsieJavaScriptEngine.csproj", "{3C9CD486-50AD-476E-9515-3F85EBAFCC38}"
2020
EndProject
21+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MsieJavaScriptEngine.Benchmarks", "test\MsieJavaScriptEngine.Benchmarks\MsieJavaScriptEngine.Benchmarks.csproj", "{A304B8BE-B946-453B-B2B5-D21305A299F8}"
22+
EndProject
2123
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MsieJavaScriptEngine.Test.Common", "test\MsieJavaScriptEngine.Test.Common\MsieJavaScriptEngine.Test.Common.csproj", "{6E4AF7B9-3257-4D35-8F5C-CBA1A7158CAB}"
2224
EndProject
2325
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MsieJavaScriptEngine.Test.Auto", "test\MsieJavaScriptEngine.Test.Auto\MsieJavaScriptEngine.Test.Auto.csproj", "{3DD423C5-DC32-42D4-9924-B5D8C2F23195}"
@@ -64,6 +66,10 @@ Global
6466
{72233C70-DF61-449F-8D53-D456284CDA5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
6567
{72233C70-DF61-449F-8D53-D456284CDA5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
6668
{72233C70-DF61-449F-8D53-D456284CDA5D}.Release|Any CPU.Build.0 = Release|Any CPU
69+
{A304B8BE-B946-453B-B2B5-D21305A299F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
70+
{A304B8BE-B946-453B-B2B5-D21305A299F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
71+
{A304B8BE-B946-453B-B2B5-D21305A299F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
72+
{A304B8BE-B946-453B-B2B5-D21305A299F8}.Release|Any CPU.Build.0 = Release|Any CPU
6773
EndGlobalSection
6874
GlobalSection(SolutionProperties) = preSolution
6975
HideSolutionNode = FALSE
@@ -77,6 +83,7 @@ Global
7783
{5864D57D-2EB8-4684-9908-26111127E75B} = {1F9B41F3-53ED-4254-98B7-F4309EA0D53E}
7884
{EF54F02A-7ECD-4D3E-9163-33BCA969FD1B} = {1F9B41F3-53ED-4254-98B7-F4309EA0D53E}
7985
{72233C70-DF61-449F-8D53-D456284CDA5D} = {1F9B41F3-53ED-4254-98B7-F4309EA0D53E}
86+
{A304B8BE-B946-453B-B2B5-D21305A299F8} = {1F9B41F3-53ED-4254-98B7-F4309EA0D53E}
8087
EndGlobalSection
8188
GlobalSection(ExtensibilityGlobals) = postSolution
8289
SolutionGuid = {5035D2B6-B7C8-4A7F-8764-07B60AD66E96}

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"sdk": {
3-
"version": "2.1.403"
3+
"version": "2.1.500"
44
}
55
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using System.Text;
3+
4+
namespace MsieJavaScriptEngine.Benchmarks
5+
{
6+
internal static class Assert
7+
{
8+
public static void Equal(string expected, string actual)
9+
{
10+
if (actual != expected)
11+
{
12+
var messageBuilder = new StringBuilder();
13+
messageBuilder.AppendLine("Assert.Equal() Failure");
14+
messageBuilder.AppendLine();
15+
messageBuilder.AppendLine($"Expected: {expected}");
16+
messageBuilder.Append($"Actual: {actual}");
17+
18+
string errorMessage = messageBuilder.ToString();
19+
20+
throw new InvalidOperationException(errorMessage);
21+
}
22+
}
23+
}
24+
}
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
using System;
2+
using System.IO;
3+
using System.Reflection;
4+
5+
using BenchmarkDotNet.Attributes;
6+
using BenchmarkDotNet.Diagnosers;
7+
using BenchmarkDotNet.Order;
8+
9+
namespace MsieJavaScriptEngine.Benchmarks
10+
{
11+
[MemoryDiagnoser]
12+
[Orderer(SummaryOrderPolicy.Method, MethodOrderPolicy.Declared)]
13+
public class JsExecutionBenchmark
14+
{
15+
/// <summary>
16+
/// Name of the file containing library for transliteration of Russian
17+
/// </summary>
18+
private const string LibraryFileName = "russian-translit.js";
19+
20+
/// <summary>
21+
/// Name of transliterate function
22+
/// </summary>
23+
private const string FunctionName = "transliterate";
24+
25+
/// <summary>
26+
/// Number of transliterated items
27+
/// </summary>
28+
private const int ItemCount = 6;
29+
30+
/// <summary>
31+
/// Code of library for transliteration of Russian
32+
/// </summary>
33+
private static string _libraryCode;
34+
35+
/// <summary>
36+
/// List of transliteration types
37+
/// </summary>
38+
private static string[] _inputTypes;
39+
40+
/// <summary>
41+
/// List of input strings
42+
/// </summary>
43+
private static string[] _inputStrings;
44+
45+
/// <summary>
46+
/// List of target output strings
47+
/// </summary>
48+
private static string[] _targetOutputStrings;
49+
50+
51+
/// <summary>
52+
/// Static constructor
53+
/// </summary>
54+
static JsExecutionBenchmark()
55+
{
56+
PopulateTestData();
57+
}
58+
59+
60+
/// <summary>
61+
/// Populates a test data
62+
/// </summary>
63+
public static void PopulateTestData()
64+
{
65+
Type type = typeof(JsExecutionBenchmark);
66+
Assembly assembly = type.Assembly;
67+
string resourceName = type.Namespace + ".Resources." + LibraryFileName;
68+
69+
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
70+
using (StreamReader reader = new StreamReader(stream))
71+
{
72+
_libraryCode = reader.ReadToEnd();
73+
}
74+
75+
_inputTypes = new string[ItemCount]
76+
{
77+
"basic", "letters-numbers", "gost-16876-71", "gost-7-79-2000", "police", "foreign-passport"
78+
};
79+
_inputStrings = new string[ItemCount]
80+
{
81+
"SOLID — мнемонический акроним, введённый Майклом Фэзерсом для первых пяти принципов, названных " +
82+
"Робертом Мартином в начале 2000-х, которые означали пять основных принципов объектно-ориентированного " +
83+
"программирования и проектирования.",
84+
85+
"Принцип единственной ответственности (The Single Responsibility Principle). " +
86+
"Каждый класс выполняет лишь одну задачу.",
87+
88+
"Принцип открытости/закрытости (The Open Closed Principle). " +
89+
"«программные сущности … должны быть открыты для расширения, но закрыты для модификации.»",
90+
91+
"Принцип подстановки Барбары Лисков (The Liskov Substitution Principle). " +
92+
"«объекты в программе должны быть заменяемыми на экземпляры их подтипов без изменения правильности выполнения программы.»",
93+
94+
"Принцип разделения интерфейса (The Interface Segregation Principle). " +
95+
"«много интерфейсов, специально предназначенных для клиентов, лучше, чем один интерфейс общего назначения.»",
96+
97+
"Принцип инверсии зависимостей (The Dependency Inversion Principle). " +
98+
"«Зависимость на Абстракциях. Нет зависимости на что-то конкретное.»"
99+
};
100+
_targetOutputStrings = new string[ItemCount]
101+
{
102+
"SOLID — mnemonicheskij akronim, vvedjonnyj Majklom Fjezersom dlja pervyh pjati principov, nazvannyh " +
103+
"Robertom Martinom v nachale 2000-h, kotorye oznachali pjat' osnovnyh principov ob#ektno-orientirovannogo " +
104+
"programmirovanija i proektirovanija.",
105+
106+
"Princip edinstvennoj otvetstvennosti (The Single Responsibility Principle). " +
107+
"Ka#dyj klass vypolnjaet li6' odnu zada4u.",
108+
109+
"Princip otkrytosti/zakrytosti (The Open Closed Principle). " +
110+
"«programmnye sushhnosti … dolzhny byt' otkryty dlja rasshirenija, no zakryty dlja modifikacii.»",
111+
112+
"Princip podstanovki Barbary Liskov (The Liskov Substitution Principle). " +
113+
"«ob\"ekty v programme dolzhny byt' zamenyaemymi na e'kzemplyary ix podtipov bez izmeneniya pravil'nosti " +
114+
"vypolneniya programmy.»",
115+
116+
"Printsip razdeleniia interfeisa (The Interface Segregation Principle). " +
117+
"«mnogo interfeisov, spetsialno prednaznachennykh dlia klientov, luchshe, chem odin interfeis obshchego " +
118+
"naznacheniia.»",
119+
120+
"Printcip inversii zavisimostei (The Dependency Inversion Principle). " +
121+
"«Zavisimost na Abstraktciiakh. Net zavisimosti na chto-to konkretnoe.»"
122+
};
123+
}
124+
125+
/// <summary>
126+
/// Transliterates a strings
127+
/// </summary>
128+
/// <param name="createJsEngine">Delegate for create an instance of the JS engine</param>
129+
/// <param name="withPrecompilation">Flag for whether to allow execution of JS code with pre-compilation</param>
130+
private static void TransliterateStrings(Func<MsieJsEngine> createJsEngine, bool withPrecompilation)
131+
{
132+
// Arrange
133+
string[] outputStrings = new string[ItemCount];
134+
PrecompiledScript precompiledCode = null;
135+
136+
// Act
137+
using (var jsEngine = createJsEngine())
138+
{
139+
if (withPrecompilation)
140+
{
141+
if (!jsEngine.SupportsScriptPrecompilation)
142+
{
143+
throw new NotSupportedException($"{jsEngine.Mode} mode does not support precompilation.");
144+
}
145+
146+
precompiledCode = jsEngine.Precompile(_libraryCode, LibraryFileName);
147+
jsEngine.Execute(precompiledCode);
148+
}
149+
else
150+
{
151+
jsEngine.Execute(_libraryCode, LibraryFileName);
152+
}
153+
154+
outputStrings[0] = jsEngine.CallFunction<string>(FunctionName, _inputStrings[0], _inputTypes[0]);
155+
}
156+
157+
for (int itemIndex = 1; itemIndex < ItemCount; itemIndex++)
158+
{
159+
using (var jsEngine = createJsEngine())
160+
{
161+
if (withPrecompilation)
162+
{
163+
jsEngine.Execute(precompiledCode);
164+
}
165+
else
166+
{
167+
jsEngine.Execute(_libraryCode, LibraryFileName);
168+
}
169+
outputStrings[itemIndex] = jsEngine.CallFunction<string>(FunctionName, _inputStrings[itemIndex],
170+
_inputTypes[itemIndex]);
171+
}
172+
}
173+
174+
// Assert
175+
for (int itemIndex = 1; itemIndex < ItemCount; itemIndex++)
176+
{
177+
Assert.Equal(_targetOutputStrings[itemIndex], outputStrings[itemIndex]);
178+
}
179+
}
180+
#if NET46
181+
182+
[Benchmark]
183+
public void Classic()
184+
{
185+
Func<MsieJsEngine> createJsEngine = () => new MsieJsEngine(new JsEngineSettings{
186+
EngineMode = JsEngineMode.Classic
187+
});
188+
TransliterateStrings(createJsEngine, false);
189+
}
190+
191+
[Benchmark]
192+
public void ChakraActiveScript()
193+
{
194+
Func<MsieJsEngine> createJsEngine = () => new MsieJsEngine(new JsEngineSettings
195+
{
196+
EngineMode = JsEngineMode.ChakraActiveScript
197+
});
198+
TransliterateStrings(createJsEngine, false);
199+
}
200+
#endif
201+
202+
[Benchmark]
203+
[Arguments(false)]
204+
[Arguments(true)]
205+
public void ChakraIeJsRt(bool withPrecompilation)
206+
{
207+
Func<MsieJsEngine> createJsEngine = () => new MsieJsEngine(new JsEngineSettings
208+
{
209+
EngineMode = JsEngineMode.ChakraIeJsRt
210+
});
211+
TransliterateStrings(createJsEngine, withPrecompilation);
212+
}
213+
214+
[Benchmark]
215+
[Arguments(false)]
216+
[Arguments(true)]
217+
public void ChakraEdgeJsRt(bool withPrecompilation)
218+
{
219+
Func<MsieJsEngine> createJsEngine = () => new MsieJsEngine(new JsEngineSettings
220+
{
221+
EngineMode = JsEngineMode.ChakraEdgeJsRt
222+
});
223+
TransliterateStrings(createJsEngine, withPrecompilation);
224+
}
225+
}
226+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<Product>MSIE JavaScript Engine: Benchmarks</Product>
5+
<VersionPrefix>3.0.0</VersionPrefix>
6+
<VersionSuffix>rc1</VersionSuffix>
7+
<TargetFrameworks>net46;netcoreapp2.0</TargetFrameworks>
8+
<OutputType>Exe</OutputType>
9+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
10+
<IsPackable>false</IsPackable>
11+
</PropertyGroup>
12+
13+
<Import Project="../../build/common.props" />
14+
15+
<ItemGroup>
16+
<PackageReference Include="BenchmarkDotNet" Version="0.11.3" />
17+
18+
<ProjectReference Include="../../src/MsieJavaScriptEngine/MsieJavaScriptEngine.csproj" />
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<EmbeddedResource Include="Resources/russian-translit.js" />
23+
</ItemGroup>
24+
25+
</Project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using BenchmarkDotNet.Running;
2+
3+
namespace MsieJavaScriptEngine.Benchmarks
4+
{
5+
public static class Program
6+
{
7+
public static void Main(string[] args)
8+
{
9+
BenchmarkRunner.Run<JsExecutionBenchmark>();
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)