Three questions
Runtime speed is the obvious one, but for an engine it is not the whole story. I measured three things:
- Runtime performance: arithmetic, filling a list, and allocating user-defined types, each 100,000 times.
- Compile time: how long a change takes to become runnable, which decides how fast designers can iterate.
- C++ interop cost: what each call across the language boundary costs, since engine scripts do little else.
Wren is a C library and needs only a thin C++ wrapper. For C# the options were P/Invoke, COM interop, embedded interop types and hosting through Mono.
// Arithmetic (C#)
for (int i = 0; i < 100000; i++)
{
int x = 0, y = 10;
int result = x * y / (i + 1);
}
// Collections (Wren)
var items = []
for (i in 1..100000) {
items.add(i * i)
}
Results
Arithmetic (µs, lower is better)
Lists (µs, lower is better)
Allocating objects (µs, lower is better)
Compile time (µs, lower is better)
Calling into C++ (ms, lower is better)
How these were measured: each runtime benchmark is one of the loops above, 100,000 iterations, written the same way in both languages. This was a short university study, not a full benchmark suite, so read the results as orders of magnitude rather than exact figures. Timings like these shift with hardware, runtime version and JIT warm-up.
A trade-off, not a winner
C# ran 6 to 15 times faster. Wren compiled over a thousand times faster, and its calls into C++ were close to free, where C# paid a real price for every crossing.
So the right choice depends on what the scripts do. Gameplay scripts in an engine mostly glue engine systems together, calling into C++ constantly and changing all the time, which favours Wren's cheap interop and instant iteration. Heavy computation belongs in C++ either way.