Adletec Sonic
NuGet Adletec.Sonic package re-bundled for convenient consumption and dependency management.
About this mod Author’s original text
sonic | rapid expression evaluation for.NET
_sonic_ is a rapid evaluation engine for mathematical expressions. It can parse and evaluate strings containing
mathematical expressions.
_sonic_ is also the expression evaluator we use in our commercial products. It is a core component of our real-time
simulation tools for virtual vehicle and ADAS prototyping and is continuously stress tested in a demanding environment.
Its development and maintenance is funded by our product sales.
Guiding Principles
The guiding principles for _sonic_ are (in that order):
- Performance: _sonic_ is aiming to be the fastest expression evaluator for.NET. It is optimized for both, multi
pass evaluation of the same expression and single pass evaluation of many different expressions.
- Usability: _sonic_ is designed to be easy to use. It comes with a sane default configuration, an understandable
documentation and a simple API. The most common use-cases should be fast out-of-the-box.
- Maintainability: _sonic_ is designed to be easy to maintain. It is written in a clean and readable code style and
comes with a comprehensive test and benchmarking suite. The NuGet package introduces no transient dependencies.
Quick Start
_sonic_ can parse and evaluate strings containing mathematical expressions. These expressions may rely on variables,
which can be defined at runtime.
Consider this example:
var expression = "var1*var2";
var variables = new Dictionary();
variables.Add("var1", 2.5);
variables.Add("var2", 3.4);
var engine = Evaluator.CreateWithDefaults();
double result = engine.Evaluate(expression, variables); // 8.5
The Evaluator comes with out-of-the-box support for many arithmetic (+, -, *, /,...),
trigonometric (sin, cos, atan,...) statistic (avg, max, min, median,...), and simple boolean
logic (if, ifless, ifequal,...) functions.
You can add your own domain-specific functions. This example adds a conversion function from length in feet (ft) to
meter (m):
var engine = Evaluator.Create().AddFunction("ft2m", (Func)((a) => a * 0.3048)).Build();
double result = engine.Evaluate("ft2m(30)"); // 9.144
You can find more examples below.
_sonic_ can execute formulas in two modes: dynamic compilation mode and interpreted mode. If dynamic
compilation mode is used, _sonic_ will create a dynamic method at runtime and will generate the MSIL opcodes necessary
for the native execution of the evaluation. If a formula is re-evaluated with other variables, _sonic_ will take the
dynamically generated method from its cache (if enabled, which it is by default). Dynamic compilation mode is a lot
faster when evaluating an expression, but has a higher overhead when building the evaluator.
As a rule of thumb, you should use dynamic compilation mode if you are evaluating the same expressions multiple
times with different variables, and interpreted mode if you are evaluating many different expressions only once.
Additionally, for specific use-cases (e.g. Unity with IL2CPP) dynamic code generation can be limited. In those cases,
you can use the interpreted mode as a fallback.
Migration from Jace.NET
_sonic_ originally started as a fork of _Jace.NET_ by Pieter De Rycke, which is
no longer actively maintained. It is not a drop-in replacement for _Jace.NET_, but you should be able to switch to
_sonic_ with little effort.
_sonic_ is considerably faster than _Jace.NET_ (see benchmarks below). It contains numerous bugfixes and a lot
of maintenance work over the latest _Jace.NET_ release (1.0.0). Many of them were originally suggested and developed
by the community for _Jace.NET_, but never merged due to the dormant state of the project. See the changelog for
details and a complete list.
Installation
_sonic_ is available via nuget:
dotnet add package Adletec.Sonic --version 1.5.0
Usage
Evaluating an Expression
Directly Evaluate an Expression
The easiest way to evaluate an expression is to use the Evaluate()-method of the Evaluator:
var expression = "var1*va
Install & use Install: BepInEx plugin
- The archive from playbuff is the mod itself — usually a BepInEx plugin (a .dll or a plugin folder once unzipped).
- Recommended: use a community mod manager (such as r2modman) — pick this game, import the mod, and the manager sets up BepInEx and its dependencies for you.
- Manual route: install the BepInEx loader in the game folder, then drop the unzipped .dll or plugin folder into BepInEx/plugins/.
- Launch the game — the BepInEx console logs every plugin it loads; seeing this mod in the log means it is installed.
Mods with listed dependencies need those installed too, or they will not load. Options are usually changed in-game or in the plugin's config file.