Add a new gas React() benchmark (#41202)
* Add a new gas React() benchmark * fix the iteration amount to 100, remove unused using * fix the iteration amount to 1000
This commit is contained in:
253
Content.Benchmarks/GasReactionBenchmark.cs
Normal file
253
Content.Benchmarks/GasReactionBenchmark.cs
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using Content.IntegrationTests;
|
||||||
|
using Content.IntegrationTests.Pair;
|
||||||
|
using Content.Server.Atmos;
|
||||||
|
using Content.Server.Atmos.EntitySystems;
|
||||||
|
using Content.Server.Atmos.Reactions;
|
||||||
|
using Content.Shared.Atmos;
|
||||||
|
using Robust.Shared;
|
||||||
|
using Robust.Shared.Analyzers;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
|
||||||
|
namespace Content.Benchmarks;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Benchmarks the performance of different gas reactions.
|
||||||
|
/// Tests each reaction type with realistic gas mixtures to measure computational cost.
|
||||||
|
/// </summary>
|
||||||
|
[Virtual]
|
||||||
|
[GcServer(true)]
|
||||||
|
[MemoryDiagnoser]
|
||||||
|
public class GasReactionBenchmark
|
||||||
|
{
|
||||||
|
private const int Iterations = 1000;
|
||||||
|
private TestPair _pair = default!;
|
||||||
|
private AtmosphereSystem _atmosphereSystem = default!;
|
||||||
|
|
||||||
|
// Grid and tile for reactions that need a holder
|
||||||
|
private EntityUid _testGrid = default!;
|
||||||
|
private TileAtmosphere _testTile = default!;
|
||||||
|
// Reaction instances
|
||||||
|
private PlasmaFireReaction _plasmaFireReaction = default!;
|
||||||
|
private TritiumFireReaction _tritiumFireReaction = default!;
|
||||||
|
private FrezonProductionReaction _frezonProductionReaction = default!;
|
||||||
|
private FrezonCoolantReaction _frezonCoolantReaction = default!;
|
||||||
|
private AmmoniaOxygenReaction _ammoniaOxygenReaction = default!;
|
||||||
|
private N2ODecompositionReaction _n2oDecompositionReaction = default!;
|
||||||
|
private WaterVaporReaction _waterVaporReaction = default!;
|
||||||
|
// Gas mixtures for each reaction type
|
||||||
|
private GasMixture _plasmaFireMixture = default!;
|
||||||
|
private GasMixture _tritiumFireMixture = default!;
|
||||||
|
private GasMixture _frezonProductionMixture = default!;
|
||||||
|
private GasMixture _frezonCoolantMixture = default!;
|
||||||
|
private GasMixture _ammoniaOxygenMixture = default!;
|
||||||
|
private GasMixture _n2oDecompositionMixture = default!;
|
||||||
|
private GasMixture _waterVaporMixture = default!;
|
||||||
|
|
||||||
|
[GlobalSetup]
|
||||||
|
public async Task SetupAsync()
|
||||||
|
{
|
||||||
|
ProgramShared.PathOffset = "../../../../";
|
||||||
|
PoolManager.Startup();
|
||||||
|
_pair = await PoolManager.GetServerClient();
|
||||||
|
var server = _pair.Server;
|
||||||
|
|
||||||
|
// Create test map and grid
|
||||||
|
var mapData = await _pair.CreateTestMap();
|
||||||
|
_testGrid = mapData.Grid;
|
||||||
|
|
||||||
|
await server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
var entMan = server.ResolveDependency<IEntityManager>();
|
||||||
|
_atmosphereSystem = entMan.System<AtmosphereSystem>();
|
||||||
|
|
||||||
|
_plasmaFireReaction = new PlasmaFireReaction();
|
||||||
|
_tritiumFireReaction = new TritiumFireReaction();
|
||||||
|
_frezonProductionReaction = new FrezonProductionReaction();
|
||||||
|
_frezonCoolantReaction = new FrezonCoolantReaction();
|
||||||
|
_ammoniaOxygenReaction = new AmmoniaOxygenReaction();
|
||||||
|
_n2oDecompositionReaction = new N2ODecompositionReaction();
|
||||||
|
_waterVaporReaction = new WaterVaporReaction();
|
||||||
|
|
||||||
|
SetupGasMixtures();
|
||||||
|
SetupTile();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupGasMixtures()
|
||||||
|
{
|
||||||
|
// Plasma Fire: Plasma + Oxygen at high temperature
|
||||||
|
// Temperature must be > PlasmaMinimumBurnTemperature for reaction to occur
|
||||||
|
_plasmaFireMixture = new GasMixture(Atmospherics.CellVolume)
|
||||||
|
{
|
||||||
|
Temperature = Atmospherics.PlasmaMinimumBurnTemperature + 100f // ~673K
|
||||||
|
};
|
||||||
|
_plasmaFireMixture.AdjustMoles(Gas.Plasma, 20f);
|
||||||
|
_plasmaFireMixture.AdjustMoles(Gas.Oxygen, 100f);
|
||||||
|
|
||||||
|
// Tritium Fire: Tritium + Oxygen at high temperature
|
||||||
|
// Temperature must be > FireMinimumTemperatureToExist for reaction to occur
|
||||||
|
_tritiumFireMixture = new GasMixture(Atmospherics.CellVolume)
|
||||||
|
{
|
||||||
|
Temperature = Atmospherics.FireMinimumTemperatureToExist + 100f // ~473K
|
||||||
|
};
|
||||||
|
_tritiumFireMixture.AdjustMoles(Gas.Tritium, 20f);
|
||||||
|
_tritiumFireMixture.AdjustMoles(Gas.Oxygen, 100f);
|
||||||
|
|
||||||
|
// Frezon Production: Oxygen + Tritium + Nitrogen catalyst
|
||||||
|
// Optimal temperature for efficiency (80% of max efficiency temp)
|
||||||
|
_frezonProductionMixture = new GasMixture(Atmospherics.CellVolume)
|
||||||
|
{
|
||||||
|
Temperature = Atmospherics.FrezonProductionMaxEfficiencyTemperature * 0.8f // ~48K
|
||||||
|
};
|
||||||
|
_frezonProductionMixture.AdjustMoles(Gas.Oxygen, 50f);
|
||||||
|
_frezonProductionMixture.AdjustMoles(Gas.Tritium, 50f);
|
||||||
|
_frezonProductionMixture.AdjustMoles(Gas.Nitrogen, 10f);
|
||||||
|
|
||||||
|
// Frezon Coolant: Frezon + Nitrogen
|
||||||
|
// Temperature must be > FrezonCoolLowerTemperature (23.15K) for reaction to occur
|
||||||
|
_frezonCoolantMixture = new GasMixture(Atmospherics.CellVolume)
|
||||||
|
{
|
||||||
|
Temperature = Atmospherics.T20C + 50f // ~343K
|
||||||
|
};
|
||||||
|
_frezonCoolantMixture.AdjustMoles(Gas.Frezon, 30f);
|
||||||
|
_frezonCoolantMixture.AdjustMoles(Gas.Nitrogen, 100f);
|
||||||
|
|
||||||
|
// Ammonia + Oxygen reaction (concentration-dependent, no temp requirement)
|
||||||
|
_ammoniaOxygenMixture = new GasMixture(Atmospherics.CellVolume)
|
||||||
|
{
|
||||||
|
Temperature = Atmospherics.T20C + 100f // ~393K
|
||||||
|
};
|
||||||
|
_ammoniaOxygenMixture.AdjustMoles(Gas.Ammonia, 40f);
|
||||||
|
_ammoniaOxygenMixture.AdjustMoles(Gas.Oxygen, 40f);
|
||||||
|
|
||||||
|
// N2O Decomposition (no temperature requirement, just needs N2O moles)
|
||||||
|
_n2oDecompositionMixture = new GasMixture(Atmospherics.CellVolume)
|
||||||
|
{
|
||||||
|
Temperature = Atmospherics.T20C + 100f // ~393K
|
||||||
|
};
|
||||||
|
_n2oDecompositionMixture.AdjustMoles(Gas.NitrousOxide, 100f);
|
||||||
|
|
||||||
|
// Water Vapor - needs water vapor to condense
|
||||||
|
_waterVaporMixture = new GasMixture(Atmospherics.CellVolume)
|
||||||
|
{
|
||||||
|
Temperature = Atmospherics.T20C
|
||||||
|
};
|
||||||
|
_waterVaporMixture.AdjustMoles(Gas.WaterVapor, 50f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupTile()
|
||||||
|
{
|
||||||
|
// Create a tile atmosphere to use as holder for all reactions
|
||||||
|
var testIndices = new Vector2i(0, 0);
|
||||||
|
_testTile = new TileAtmosphere(_testGrid, testIndices, new GasMixture(Atmospherics.CellVolume)
|
||||||
|
{
|
||||||
|
Temperature = Atmospherics.T20C
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GasMixture CloneMixture(GasMixture original)
|
||||||
|
{
|
||||||
|
return new GasMixture(original);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public async Task PlasmaFireReaction()
|
||||||
|
{
|
||||||
|
await _pair.Server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
for (var i = 0; i < Iterations; i++)
|
||||||
|
{
|
||||||
|
var mixture = CloneMixture(_plasmaFireMixture);
|
||||||
|
_plasmaFireReaction.React(mixture, _testTile, _atmosphereSystem, 1f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public async Task TritiumFireReaction()
|
||||||
|
{
|
||||||
|
await _pair.Server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
for (var i = 0; i < Iterations; i++)
|
||||||
|
{
|
||||||
|
var mixture = CloneMixture(_tritiumFireMixture);
|
||||||
|
_tritiumFireReaction.React(mixture, _testTile, _atmosphereSystem, 1f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public async Task FrezonProductionReaction()
|
||||||
|
{
|
||||||
|
await _pair.Server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
for (var i = 0; i < Iterations; i++)
|
||||||
|
{
|
||||||
|
var mixture = CloneMixture(_frezonProductionMixture);
|
||||||
|
_frezonProductionReaction.React(mixture, _testTile, _atmosphereSystem, 1f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public async Task FrezonCoolantReaction()
|
||||||
|
{
|
||||||
|
await _pair.Server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
for (var i = 0; i < Iterations; i++)
|
||||||
|
{
|
||||||
|
var mixture = CloneMixture(_frezonCoolantMixture);
|
||||||
|
_frezonCoolantReaction.React(mixture, _testTile, _atmosphereSystem, 1f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public async Task AmmoniaOxygenReaction()
|
||||||
|
{
|
||||||
|
await _pair.Server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
for (var i = 0; i < Iterations; i++)
|
||||||
|
{
|
||||||
|
var mixture = CloneMixture(_ammoniaOxygenMixture);
|
||||||
|
_ammoniaOxygenReaction.React(mixture, _testTile, _atmosphereSystem, 1f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public async Task N2ODecompositionReaction()
|
||||||
|
{
|
||||||
|
await _pair.Server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
for (var i = 0; i < Iterations; i++)
|
||||||
|
{
|
||||||
|
var mixture = CloneMixture(_n2oDecompositionMixture);
|
||||||
|
_n2oDecompositionReaction.React(mixture, _testTile, _atmosphereSystem, 1f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public async Task WaterVaporReaction()
|
||||||
|
{
|
||||||
|
await _pair.Server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
for (var i = 0; i < Iterations; i++)
|
||||||
|
{
|
||||||
|
var mixture = CloneMixture(_waterVaporMixture);
|
||||||
|
_waterVaporReaction.React(mixture, _testTile, _atmosphereSystem, 1f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[GlobalCleanup]
|
||||||
|
public async Task CleanupAsync()
|
||||||
|
{
|
||||||
|
await _pair.DisposeAsync();
|
||||||
|
PoolManager.Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user