-
Notifications
You must be signed in to change notification settings - Fork 236
Choosing Compiler Engine
CS-Script is not a true interpreter like Python nor a compiler like C++. CS-Script is a hybrid script engine that uses .NET stock compilers to compile scripts on-fly and deliver true scripting experience without losing type safety and performance of the compiled execution.
Thus, CS-Script is heavily dependent on the .NET compiling tools. These tools were always available starting from the very first release of NET. As well as the corresponding API CodeDom. And this is exactly what CS-Script was using in the early versions.
Despite the common belief, Roslyn is not the first release of compiler-as-service of .NET, CodeDom is. Though it is the first implementation that delivers complete in-process hosting. Interestingly enough, Mono has released its own version of compiler-as-service even before Roslyn, but now is obsolete.
Prior .NET 5 release CS-Script allowed the users to select any desired compiling engine supported by .NET Framework: CodeDom, Mono or Roslyn. But with the release of .NET 5 which is effectively .NET Core all other compilers became completely obsolete so the only available engine out of box was Roslyn. However, even Roslyn was not well suited for comprehensive scripting since it has a few serious practical limitations. That's why the first release of CS-Script for .NET 5 used dotnet.exe
as an out-of-process compiler-as-service compiling engine.
This engine is the most versatile engine that can be. It is capable of running scripts implementing WPF, ASP.NET, WinForms and any app type that .NET supports.
However... it is slow and it is only available with .NET 5 SDK. Meaning that in order to run scripts having .NET 5 runtime installed is not enough and you need to deploy .NET SDK as well.
Thus, in order to overcome these limitations and after the initial feedback from users, CS-Script v4.0.3 was extended with support for extra new compiling engines: in-process Roslyn and csc.exe
compiling services.
Note, depending on the scripting model being CLI or Hosted you may find that your choice of the compiler engine needs to be based on different criteria. That is why this page describes these criteria in separate independent sections "CS-Script CLI" and "Hosting CS-Script".
Engine Name | dotnet | csc | roslyn |
---|---|---|---|
Available for CS-Script CLI | yes | yes | yes |
Available for CS-Script Hosted | no | yes | yes |
File | dotnet.exe | csc.exe | Microsoft.CodeAnalysis.CSharp.Scripting.dll |
Prerequisite | .NET SDK | .NET SDK | .NET Runtime |
Performance (first run) | poor | very good | very good |
Performance (consecutive runs) | perfect | perfect | perfect |
Multi-module scripts | yes | yes | yes (conditional) |
Support XAML compilation (WPF) | yes | no | no |
Namespace declarations allowed | yes | yes | no |
A more detailed comparative review of the engines in the specific scenarios is provided in the Compiler technology comparison section of this article. This is because some of the limitations are imposed not by the engine itself but by the hosting model chosen.
When using CS-Script CLI css.exe
you can choose your desired compiling engine (dotnet
, csc
, roslyn
) either per-script execution or system-wide.
From command line:
css -engine:csc <script file>
or
css -ng:csc <script file>
From script code:
//css_engine roslyn
or
//css_ng roslyn
css -config:set:DefaultCompilerEngine=dotnet
The default engine is dotnet
for Windows and csc
for all other OS.
When hosting CS-Script CSScriptLib.dll
you have to choose the desired compiling engines: EvaluatorEngine.Roslyn
and EvaluatorEngine.CodeDom
.
Note, the CodeDom engine redirects the compiling requests to the out-of-process csc.exe
compiler and Roslyn (default) redirects the requests to the in-process Roslyn compiling service.
dynamic script = CSScript.RoslynEvaluator
.LoadMethod(@"public int add(int a, int b)
{
return a + b;
}");
CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom;
. . .
dynamic script = CSScript.Evaluator
.LoadMethod(@"public int add(int a, int b)
{
return a + b;
}");
This section contains a detailed analysis of the aspects of compiler engine selection. But a very concise summary of the comparative analysis in the table below.
Features | dotnet (default on Windows) | csc (default on non-Windows) | roslyn |
---|---|---|---|
Performance (first execution)1 |
poor | excellent2 | very good3 |
Performance (next execution)4 |
perfect | perfect | perfect |
Need SDK installed 6 | yes | yes | no |
Namespace declarations allowed | yes | yes | no |
Support XAML compilation (WPF) | yes | no | yes |
WinForms | yes | yes | yes |
Support for NuGet packages | full | full | no |
Support for //css_include and //css_import
|
full | full | partial5 |
1 - The execution of the script that was just created or modified.
2 - The csc.exe
based compiling service needs to be running. It is started automatically if it is not already running. Service runs on socket port 17001 (can be overwritten via environment variable CSS_BUILDSERVER_CSC_PORT)
3 - The Roslyn based compiling service needs to be running. It is started automatically if it is not already running. Service runs on socket port 17002 (can be overwritten via environment variable CSS_BUILDSERVER_ROSLYN_PORT)
4 - Any execution that is not "first execution" while CS-Script caching is enabled (see CLI -c
). It's enabled by default.
5 - Roslyn API does not allow multi-module scripting thus CS-Script merges multiple scripts into a single script. This can potentially lead to C# syntax errors (e.g. namespace collisions).
6 - Deployment of SDK is beyond this article scope. Visit .NET Download for details.
Features | EvaluatorEngine.CodeDom/csc | EvaluatorEngine.Roslyn/roslyn (default) |
---|---|---|
Performance (first execution) | very good | excellent |
Performance (next execution)1 | perfect | perfect |
Need SDK installed 2 | yes | no |
Namespace declarations allowed | yes | no |
Support XAML compilation (WPF) | no | no |
WinForms 3 | n/a | n/a |
Support for NuGet packages 4 | n/a | n/a |
Support for //css_include and //css_import
|
full | partial5 |
1 - If your scripting scenario involves executing the same script(s) again and again ("next execution" o the same script) you can improve performance up to the level of the compiled assembly by enabling caching. Caching is disabled by default.
CSScript.Evaluator
.With(eval => eval.IsCachingEnabled = true)
.LoadMethod(<script code>);
2 - Deployment of SDK is beyond this article scope. Visit .NET Download for details.
3 - CS-Script WinForm support is about being able to start the scripted app without the console window attached. So it is not applicable to the hosted script execution as the application startup is completely managed by the host application.
4 - Dynamic downloading of the dependency packages is not applicable to the script engine as it is the responsibility of the host application. This approach is consistent with the majority of the scripting frameworks (e.g. Python).
5 - Roslyn API does not allow multi-module scripting thus CS-Script merges multiple scripts into a single script. This can potentially lead to C# syntax errors (e.g. namespace collisions).
Pros
- It is the most flexible engine. It is tunnelling the script compilation to the .NET application builder (
dotnet.exe
). Meaning that the script can be defined the same way as any application type supported by .NET 5 and higher. It can even be a WPF application implemented as a script.
Cons
- Slow to start up. Caching solves the problem but if your script is frequently changed then the startup penalty will be paid every time you change something in your script.
- Requires .NET 5 SDK to be installed on the target system.
Pros
-
It is quite flexible as it is tunnelling the script compilation to the C# compiler
csc.exe
. -
It is very fast to load.
Note: Requires csc out-of-process compiling service running. It starts on the first execution of a script and remains active till the OS restarts. It is CS-Script own equivalent of
VBCSCompiler.exe
(hot-startcsc.exe
launcher) that was available in .NET Framework but sadly is broken in .NET5.
Cons
- Cannot compile XAML (WPF scripts).
- Requires .NET 5 SDK to be installed on the target system.
Pros
-
It is the only engine that does not require SDK installed. .NET 5 runtime is fully sufficient to run the scripts.
-
It is very fast to load.
Note: Requires roslyn out-of-process compiling service running. It starts on the first execution of a script and remains active till the OS restarts. It is conceptually similar to
VBCSCompiler.exe
as it simply ensures hot-start launchingcscs.exe
(another instance of CS-Script process) that uses Roslyn compiler to compile the scripts into assemblies.
Cons
- Cannot reference Nuget packages.
- Requires special considerations when importing other scripts into the master script as they are simply merged together. This may lead to the collisions of the
using <namespace>;
statements. - Does not allow multi-module scripting. Meaning that when importing the scripts, CS-Script simply merges imported scripts with the primary script into a single combined script. And this in turn can potentially lead to C# syntax errors (e.g. namespaces collisions).
- Declaring namespaces is prohibited by the underlying Roslyn compiler.