Browse Source

Update: benchmarks

AnnulusGames 1 year ago
parent
commit
aa702ba84d

+ 23 - 2
sandbox/Benchmark/AddBenchmark.cs

@@ -8,12 +8,21 @@ public class AddBenchmark
     BenchmarkCore core = new();
     LuaValue[] buffer = new LuaValue[1];
 
-    [GlobalSetup]
-    public void GlobalSetup()
+    [IterationSetup]
+    public void Setup()
     {
+        core = new();
         core.Setup("add.lua");
     }
 
+    [IterationCleanup]
+    public void Cleanup()
+    {
+        core.Dispose();
+        core = default!;
+        GC.Collect();
+    }
+
     [Benchmark(Description = "MoonSharp (RunString)")]
     public DynValue Benchmark_MoonSharp_String()
     {
@@ -38,6 +47,18 @@ public class AddBenchmark
         return core.NLuaState.DoFile(core.FilePath);
     }
 
+    [Benchmark(Description = "NeoLua (DoChunk(code))")]
+    public Neo.IronLua.LuaResult Benchmark_NeoLua_String()
+    {
+        return core.NeoLuaEnvironment.DoChunk(core.SourceText, "chunk");
+    }
+
+    [Benchmark(Description = "NeoLua (DoChunk(fileName))")]
+    public Neo.IronLua.LuaResult Benchmark_NeoLua_File()
+    {
+        return core.NeoLuaEnvironment.DoChunk(core.FilePath);
+    }
+
     [Benchmark(Description = "Lua-CSharp (DoString)")]
     public async Task<LuaValue> Benchmark_LuaCSharp_String()
     {

+ 1 - 0
sandbox/Benchmark/Benchmark.csproj

@@ -10,6 +10,7 @@
   <ItemGroup>
     <PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
     <PackageReference Include="MoonSharp" Version="2.0.0" />
+    <PackageReference Include="NeoLua" Version="1.3.14" />
     <PackageReference Include="NLua" Version="1.7.3" />
   </ItemGroup>
 

+ 14 - 1
sandbox/Benchmark/BenchmarkCore.cs

@@ -1,15 +1,18 @@
 using Lua;
 using MoonSharp.Interpreter;
 
-public class BenchmarkCore
+public class BenchmarkCore : IDisposable
 {
     public NLua.Lua NLuaState => nLuaState;
+    public Neo.IronLua.LuaGlobal NeoLuaEnvironment => neoLuaEnvironment;
     public Script MoonSharpState => moonSharpState;
     public LuaState LuaCSharpState => luaCSharpState;
     public string FilePath => filePath;
     public string SourceText => sourceText;
 
     NLua.Lua nLuaState = default!;
+    Neo.IronLua.Lua neoLuaState = default!;
+    Neo.IronLua.LuaGlobal neoLuaEnvironment = default!;
     Script moonSharpState = default!;
     LuaState luaCSharpState = default!;
     string filePath = default!;
@@ -24,10 +27,20 @@ public class BenchmarkCore
         // NLua
         nLuaState = new();
 
+        // NeoLua
+        neoLuaState = new();
+        neoLuaEnvironment = neoLuaState.CreateEnvironment();
+
         // Lua-CSharp
         luaCSharpState = LuaState.Create();
 
         filePath = FileHelper.GetAbsolutePath(fileName);
         sourceText = File.ReadAllText(filePath);
     }
+
+    public void Dispose()
+    {
+        nLuaState.Dispose();
+        neoLuaState.Dispose();
+    }
 }

+ 12 - 3
sandbox/Benchmark/InterpreterSteps.cs

@@ -3,6 +3,7 @@ using Lua;
 using Lua.CodeAnalysis.Compilation;
 using Lua.CodeAnalysis.Syntax;
 using Lua.Runtime;
+using Lua.Standard;
 
 [Config(typeof(BenchmarkConfig))]
 public class InterpreterSteps
@@ -17,11 +18,9 @@ public class InterpreterSteps
     [GlobalSetup]
     public void GlobalSetup()
     {
-        var filePath = FileHelper.GetAbsolutePath("add.lua");
+        var filePath = FileHelper.GetAbsolutePath("n-body.lua");
         sourceText = File.ReadAllText(filePath);
 
-        state = LuaState.Create();
-
         var lexer = new Lexer
         {
             Source = sourceText.AsMemory()
@@ -45,6 +44,16 @@ public class InterpreterSteps
         chunk = LuaCompiler.Default.Compile(ast);
     }
 
+    [IterationSetup]
+    public void Setup()
+    {
+        state = default!;
+        GC.Collect();
+
+        state = LuaState.Create();
+        state.OpenStandardLibraries();
+    }
+
     [Benchmark]
     public void CreateState()
     {

+ 77 - 0
sandbox/Benchmark/NBodyBenchmark.cs

@@ -0,0 +1,77 @@
+using BenchmarkDotNet.Attributes;
+using Lua;
+using Lua.Standard;
+using MoonSharp.Interpreter;
+
+[Config(typeof(BenchmarkConfig))]
+public class NBodyBenchmark
+{
+    BenchmarkCore core = default!;
+    LuaValue[] buffer = new LuaValue[1];
+
+    [IterationSetup]
+    public void Setup()
+    {
+        core = new();
+        core.Setup("n-body.lua");
+        core.LuaCSharpState.OpenStandardLibraries();
+    }
+
+    [IterationCleanup]
+    public void Cleanup()
+    {
+        core.Dispose();
+        core = default!;
+        GC.Collect();
+    }
+
+    [Benchmark(Description = "MoonSharp (RunString)")]
+    public DynValue Benchmark_MoonSharp_String()
+    {
+        return core.MoonSharpState.DoString(core.SourceText);
+    }
+
+    [Benchmark(Description = "MoonSharp (RunFile)")]
+    public DynValue Benchmark_MoonSharp_File()
+    {
+        return core.MoonSharpState.DoFile(core.FilePath);
+    }
+
+    [Benchmark(Description = "NLua (DoString)")]
+    public object[] Benchmark_NLua_String()
+    {
+        return core.NLuaState.DoString(core.SourceText);
+    }
+
+    [Benchmark(Description = "NLua (DoFile)")]
+    public object[] Benchmark_NLua_File()
+    {
+        return core.NLuaState.DoFile(core.FilePath);
+    }
+
+    [Benchmark(Description = "NeoLua (DoChunk(code))")]
+    public Neo.IronLua.LuaResult Benchmark_NeoLua_String()
+    {
+        return core.NeoLuaEnvironment.DoChunk(core.SourceText, "chunk");
+    }
+
+    [Benchmark(Description = "NeoLua (DoChunk(fileName))")]
+    public Neo.IronLua.LuaResult Benchmark_NeoLua_File()
+    {
+        return core.NeoLuaEnvironment.DoChunk(core.FilePath);
+    }
+
+    [Benchmark(Description = "Lua-CSharp (DoString)")]
+    public async Task<LuaValue> Benchmark_LuaCSharp_String()
+    {
+        await core.LuaCSharpState.DoStringAsync(core.SourceText, buffer);
+        return buffer[0];
+    }
+
+    [Benchmark(Description = "Lua-CSharp (DoFileAsync)")]
+    public async Task<LuaValue> Benchmark_LuaCSharp_File()
+    {
+        await core.LuaCSharpState.DoFileAsync(core.FilePath, buffer);
+        return buffer[0];
+    }
+}

+ 115 - 0
sandbox/Benchmark/n-body.lua

@@ -0,0 +1,115 @@
+sun = {}
+jupiter = {}
+saturn = {}
+uranus = {}
+neptune = {}
+
+local sqrt = math.sqrt
+
+local PI = 3.141592653589793
+local SOLAR_MASS = 4 * PI * PI
+local DAYS_PER_YEAR = 365.24
+sun.x = 0.0
+sun.y = 0.0
+sun.z = 0.0
+sun.vx = 0.0
+sun.vy = 0.0
+sun.vz = 0.0
+sun.mass = SOLAR_MASS
+jupiter.x = 4.84143144246472090e+00
+jupiter.y = -1.16032004402742839e+00
+jupiter.z = -1.03622044471123109e-01
+jupiter.vx = 1.66007664274403694e-03 * DAYS_PER_YEAR
+jupiter.vy = 7.69901118419740425e-03 * DAYS_PER_YEAR
+jupiter.vz = -6.90460016972063023e-05 * DAYS_PER_YEAR
+jupiter.mass = 9.54791938424326609e-04 * SOLAR_MASS
+saturn.x = 8.34336671824457987e+00
+saturn.y = 4.12479856412430479e+00
+saturn.z = -4.03523417114321381e-01
+saturn.vx = -2.76742510726862411e-03 * DAYS_PER_YEAR
+saturn.vy = 4.99852801234917238e-03 * DAYS_PER_YEAR
+saturn.vz = 2.30417297573763929e-05 * DAYS_PER_YEAR
+saturn.mass = 2.85885980666130812e-04 * SOLAR_MASS
+uranus.x = 1.28943695621391310e+01
+uranus.y = -1.51111514016986312e+01
+uranus.z = -2.23307578892655734e-01
+uranus.vx = 2.96460137564761618e-03 * DAYS_PER_YEAR
+uranus.vy = 2.37847173959480950e-03 * DAYS_PER_YEAR
+uranus.vz = -2.96589568540237556e-05 * DAYS_PER_YEAR
+uranus.mass = 4.36624404335156298e-05 * SOLAR_MASS
+neptune.x = 1.53796971148509165e+01
+neptune.y = -2.59193146099879641e+01
+neptune.z = 1.79258772950371181e-01
+neptune.vx = 2.68067772490389322e-03 * DAYS_PER_YEAR
+neptune.vy = 1.62824170038242295e-03 * DAYS_PER_YEAR
+neptune.vz = -9.51592254519715870e-05 * DAYS_PER_YEAR
+neptune.mass = 5.15138902046611451e-05 * SOLAR_MASS
+
+local bodies = { sun, jupiter, saturn, uranus, neptune }
+
+local function advance(bodies, nbody, dt)
+    for i = 1, nbody do
+        local bi = bodies[i]
+        local bix, biy, biz, bimass = bi.x, bi.y, bi.z, bi.mass
+        local bivx, bivy, bivz = bi.vx, bi.vy, bi.vz
+        for j = i + 1, nbody do
+            local bj = bodies[j]
+            local dx, dy, dz = bix - bj.x, biy - bj.y, biz - bj.z
+            local dist2 = dx * dx + dy * dy + dz * dz
+            local mag = sqrt(dist2)
+            mag = dt / (mag * dist2)
+            local bm = bj.mass * mag
+            bivx = bivx - (dx * bm)
+            bivy = bivy - (dy * bm)
+            bivz = bivz - (dz * bm)
+            bm = bimass * mag
+            bj.vx = bj.vx + (dx * bm)
+            bj.vy = bj.vy + (dy * bm)
+            bj.vz = bj.vz + (dz * bm)
+        end
+        bi.vx = bivx
+        bi.vy = bivy
+        bi.vz = bivz
+        bi.x = bix + dt * bivx
+        bi.y = biy + dt * bivy
+        bi.z = biz + dt * bivz
+    end
+end
+
+local function energy(bodies, nbody)
+    local e = 0
+    for i = 1, nbody do
+        local bi = bodies[i]
+        local vx, vy, vz, bim = bi.vx, bi.vy, bi.vz, bi.mass
+        e = e + (0.5 * bim * (vx * vx + vy * vy + vz * vz))
+        for j = i + 1, nbody do
+            local bj = bodies[j]
+            local dx, dy, dz = bi.x - bj.x, bi.y - bj.y, bi.z - bj.z
+            local distance = sqrt(dx * dx + dy * dy + dz * dz)
+            e = e - ((bim * bj.mass) / distance)
+        end
+    end
+    return e
+end
+
+local function offsetMomentum(b, nbody)
+    local px, py, pz = 0, 0, 0
+    for i = 1, nbody do
+        local bi = b[i]
+        local bim = bi.mass
+        px = px + (bi.vx * bim)
+        py = py + (bi.vy * bim)
+        pz = pz + (bi.vz * bim)
+    end
+    b[1].vx = -px / SOLAR_MASS
+    b[1].vy = -py / SOLAR_MASS
+    b[1].vz = -pz / SOLAR_MASS
+end
+
+local N = tonumber(arg and arg[1]) or 1000
+local nbody = #bodies
+
+offsetMomentum(bodies, nbody)
+energy(bodies, nbody)
+for i = 1, N do advance(bodies, nbody, 0.01) end
+energy(bodies, nbody)

+ 115 - 2
sandbox/ConsoleApp1/test.lua

@@ -1,2 +1,115 @@
-local math = require "math"
-return math.pi;
+sun = {}
+jupiter = {}
+saturn = {}
+uranus = {}
+neptune = {}
+
+local sqrt = math.sqrt
+
+local PI = 3.141592653589793
+local SOLAR_MASS = 4 * PI * PI
+local DAYS_PER_YEAR = 365.24
+sun.x = 0.0
+sun.y = 0.0
+sun.z = 0.0
+sun.vx = 0.0
+sun.vy = 0.0
+sun.vz = 0.0
+sun.mass = SOLAR_MASS
+jupiter.x = 4.84143144246472090e+00
+jupiter.y = -1.16032004402742839e+00
+jupiter.z = -1.03622044471123109e-01
+jupiter.vx = 1.66007664274403694e-03 * DAYS_PER_YEAR
+jupiter.vy = 7.69901118419740425e-03 * DAYS_PER_YEAR
+jupiter.vz = -6.90460016972063023e-05 * DAYS_PER_YEAR
+jupiter.mass = 9.54791938424326609e-04 * SOLAR_MASS
+saturn.x = 8.34336671824457987e+00
+saturn.y = 4.12479856412430479e+00
+saturn.z = -4.03523417114321381e-01
+saturn.vx = -2.76742510726862411e-03 * DAYS_PER_YEAR
+saturn.vy = 4.99852801234917238e-03 * DAYS_PER_YEAR
+saturn.vz = 2.30417297573763929e-05 * DAYS_PER_YEAR
+saturn.mass = 2.85885980666130812e-04 * SOLAR_MASS
+uranus.x = 1.28943695621391310e+01
+uranus.y = -1.51111514016986312e+01
+uranus.z = -2.23307578892655734e-01
+uranus.vx = 2.96460137564761618e-03 * DAYS_PER_YEAR
+uranus.vy = 2.37847173959480950e-03 * DAYS_PER_YEAR
+uranus.vz = -2.96589568540237556e-05 * DAYS_PER_YEAR
+uranus.mass = 4.36624404335156298e-05 * SOLAR_MASS
+neptune.x = 1.53796971148509165e+01
+neptune.y = -2.59193146099879641e+01
+neptune.z = 1.79258772950371181e-01
+neptune.vx = 2.68067772490389322e-03 * DAYS_PER_YEAR
+neptune.vy = 1.62824170038242295e-03 * DAYS_PER_YEAR
+neptune.vz = -9.51592254519715870e-05 * DAYS_PER_YEAR
+neptune.mass = 5.15138902046611451e-05 * SOLAR_MASS
+
+local bodies = { sun, jupiter, saturn, uranus, neptune }
+
+local function advance(bodies, nbody, dt)
+    for i = 1, nbody do
+        local bi = bodies[i]
+        local bix, biy, biz, bimass = bi.x, bi.y, bi.z, bi.mass
+        local bivx, bivy, bivz = bi.vx, bi.vy, bi.vz
+        for j = i + 1, nbody do
+            local bj = bodies[j]
+            local dx, dy, dz = bix - bj.x, biy - bj.y, biz - bj.z
+            local dist2 = dx * dx + dy * dy + dz * dz
+            local mag = sqrt(dist2)
+            mag = dt / (mag * dist2)
+            local bm = bj.mass * mag
+            bivx = bivx - (dx * bm)
+            bivy = bivy - (dy * bm)
+            bivz = bivz - (dz * bm)
+            bm = bimass * mag
+            bj.vx = bj.vx + (dx * bm)
+            bj.vy = bj.vy + (dy * bm)
+            bj.vz = bj.vz + (dz * bm)
+        end
+        bi.vx = bivx
+        bi.vy = bivy
+        bi.vz = bivz
+        bi.x = bix + dt * bivx
+        bi.y = biy + dt * bivy
+        bi.z = biz + dt * bivz
+    end
+end
+
+local function energy(bodies, nbody)
+    local e = 0
+    for i = 1, nbody do
+        local bi = bodies[i]
+        local vx, vy, vz, bim = bi.vx, bi.vy, bi.vz, bi.mass
+        e = e + (0.5 * bim * (vx * vx + vy * vy + vz * vz))
+        for j = i + 1, nbody do
+            local bj = bodies[j]
+            local dx, dy, dz = bi.x - bj.x, bi.y - bj.y, bi.z - bj.z
+            local distance = sqrt(dx * dx + dy * dy + dz * dz)
+            e = e - ((bim * bj.mass) / distance)
+        end
+    end
+    return e
+end
+
+local function offsetMomentum(b, nbody)
+    local px, py, pz = 0, 0, 0
+    for i = 1, nbody do
+        local bi = b[i]
+        local bim = bi.mass
+        px = px + (bi.vx * bim)
+        py = py + (bi.vy * bim)
+        pz = pz + (bi.vz * bim)
+    end
+    b[1].vx = -px / SOLAR_MASS
+    b[1].vy = -py / SOLAR_MASS
+    b[1].vz = -pz / SOLAR_MASS
+end
+
+local N = tonumber(arg and arg[1]) or 1000
+local nbody = #bodies
+
+offsetMomentum(bodies, nbody)
+energy(bodies, nbody)
+for i = 1, N do advance(bodies, nbody, 0.01) end
+energy(bodies, nbody)