Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated fennecs to 0.4.0-beta #36

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ All results are obtained from the same toaster, with the same load, so compariso
Tested frameworks:
- [Arch](https://github.com/genaray/Arch)
- [DefaultEcs](https://github.com/Doraku/DefaultEcs)
- [Fennecs](https://github.com/thygrrr/fennecs)
- [**fenn**ecs](https://fennecs.tech)
- [Flecs.Net](https://github.com/BeanCheeseBurrito/Flecs.NET)
- [Friflo.Engine.ECS](https://github.com/friflo/Friflo.Json.Fliox/blob/main/Engine/README.md)
- [Leopotam.Ecs](https://github.com/Leopotam/ecs) using what I believe is a nuget package not made by the actual author and compiled in debug...
Expand Down
69 changes: 69 additions & 0 deletions source/Ecs.CSharp.Benchmark/Capabilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using BenchmarkDotNet.Configs;

namespace Ecs.CSharp.Benchmark
{
/// <summary>
/// Capability Requirements for specific tests.
/// Add your own intrinsics or other system dependencies here.
/// </summary>
/// <remarks>
/// Usage: Add a category to it and apply exclusions in the ApplyExclusions method.
/// (this is an EXCLUSIVE category filter, it turns OFF all categories it matches)
/// Then, set your own BenchmarkCategory to include the CapabilityCategory string.
/// </remarks>
/// <example>
/// <code>
/// [BenchmarkCategory(
/// Categories.Fennecs,
/// Capabilities.Avx2
/// )]
/// public void Raw_AVX2()
/// </code>
/// </example>
internal static class Capabilities
{
// These are common vectorized instruction set categories.
// x86/x64
public const string Avx2 = nameof(System.Runtime.Intrinsics.X86.Avx2);
public const string Avx = nameof(System.Runtime.Intrinsics.X86.Avx);
public const string Sse3 = nameof(System.Runtime.Intrinsics.X86.Sse3);
public const string Sse2 = nameof(System.Runtime.Intrinsics.X86.Sse2);

// Arm
public const string AdvSimd = nameof(System.Runtime.Intrinsics.Arm.AdvSimd);

/// <summary>
/// This applies capability-based exclusions as filters to the config.
/// </summary>
/// <param name="self">a Benchmark Config, e.g. as used in Program.cs</param>
public static IConfig WithCapabilityExclusions(this IConfig self)
{
if (!System.Runtime.Intrinsics.X86.Avx2.IsSupported)
{
self = self.AddFilter(new CategoryExclusion(Avx2));
}

if (!System.Runtime.Intrinsics.X86.Avx.IsSupported)
{
self = self.AddFilter(new CategoryExclusion(Avx));
}

if (!System.Runtime.Intrinsics.X86.Sse3.IsSupported)
{
self = self.AddFilter(new CategoryExclusion(Sse3));
}

if (!System.Runtime.Intrinsics.X86.Sse2.IsSupported)
{
self = self.AddFilter(new CategoryExclusion(Sse2));
}

if (!System.Runtime.Intrinsics.Arm.AdvSimd.IsSupported)
{
self = self.AddFilter(new CategoryExclusion(AdvSimd));
}

return self;
}
}
}
30 changes: 28 additions & 2 deletions source/Ecs.CSharp.Benchmark/Categories.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
namespace Ecs.CSharp.Benchmark
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using BenchmarkDotNet.Filters;
using BenchmarkDotNet.Running;

namespace Ecs.CSharp.Benchmark
{
/// <summary>
/// Prefixes / ECS package names for benchmarks, used as BenchMarkDotNet categories.
/// </summary>
internal static class Categories
{
public const string Arch = "Arch";
Expand All @@ -14,10 +22,28 @@ internal static class Categories
public const string SveltoECS = "Svelto.ECS";
public const string Morpeh = "Morpeh";
public const string FlecsNet = "FlecsNet";
public const string Fennecs = "Fennecs";
public const string Fennecs = "fennecs";
public const string TinyEcs = "TinyEcs";

public const string CreateEntity = "CreateEntity";
public const string System = "System";
}

/// <summary>
/// Excludes a given category from benchmarks.
/// (used by Program.cs)
/// </summary>
/// <remarks>
/// When an exclusion is PRESENT, then all benchmarks that HAVE the category will be EXCLUDED.
/// </remarks>
/// <example>
/// <c>CategoryExclusion("foo")</c> will exclude all benchmarks that have the "foo" category.
/// </example>
public class CategoryExclusion(string category) : IFilter
{
public bool Predicate([NotNull] BenchmarkCase benchmarkCase)
{
return !benchmarkCase.Descriptor.Categories.Contains(category);
}
}
}
36 changes: 25 additions & 11 deletions source/Ecs.CSharp.Benchmark/Contexts/FennecsBaseContext.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,52 @@
using System;
using System.Runtime.CompilerServices;
using fennecs;

namespace Ecs.CSharp.Benchmark.Contexts
{
namespace Fennecs_Components
{
internal struct Component1
internal record struct Component1
{
public static implicit operator Component1(int value) => new() { Value = value };
public static implicit operator Component2(Component1 self) => new() { Value = self.Value };
public static implicit operator Component3(Component1 self) => new() { Value = self.Value };
public static implicit operator int (Component1 c) => c.Value;

public int Value;
}

internal struct Component2
internal record struct Component2
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Component1(Component2 self) => new() { Value = self.Value };
public static implicit operator Component2(int value) => new() { Value = value };
public static implicit operator Component3(Component2 self) => new() { Value = self.Value };
public static implicit operator int (Component2 c) => c.Value;

public int Value;
}

internal struct Component3
internal record struct Component3
{
public static implicit operator Component1(Component3 self) => new() { Value = self.Value };
public static implicit operator Component2(Component3 self) => new() { Value = self.Value };
public static implicit operator Component3(int value) => new() { Value = value };
public static implicit operator int (Component3 c) => c.Value;

public int Value;
}
}

internal class FennecsBaseContext : IDisposable
internal class FennecsBaseContext(int entityCount) : IDisposable
{
public World World { get; }
public World World { get; } = new World(entityCount * 2);

public FennecsBaseContext()
{
World = new World();
}

public void Dispose()
public virtual void Dispose()
{
World.Dispose();
}
public FennecsBaseContext() : this(100000)
{ }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@ namespace Ecs.CSharp.Benchmark
public partial class CreateEntityWithOneComponent
{
[Context] private readonly FennecsBaseContext _fennecs;

[BenchmarkCategory(Categories.Fennecs)]
[Benchmark]
[Benchmark(Description = "fennecs")]
public void Fennecs()
{
World world = _fennecs.World;

for (int i = 0; i < EntityCount; ++i)
{
world.Spawn().Add<Component1>();
}
world.Entity()
.Add(new Component1())
.Spawn(EntityCount);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,24 @@
using Ecs.CSharp.Benchmark.Contexts.Fennecs_Components;
using fennecs;

// ReSharper disable once CheckNamespace
namespace Ecs.CSharp.Benchmark
{
public partial class CreateEntityWithThreeComponents
{
[Context]
private readonly FennecsBaseContext _fennecs;

[Context] private readonly FennecsBaseContext _fennecs;

[BenchmarkCategory(Categories.Fennecs)]
[Benchmark]
[Benchmark(Description = "fennecs")]
public void Fennecs()
{
World world = _fennecs.World;

for (int i = 0; i < EntityCount; ++i)
{
world.Spawn()
.Add<Component1>()
.Add<Component2>()
.Add<Component3>();
}
world.Entity()
.Add(new Component1())
.Add(new Component2())
.Add(new Component3())
.Spawn(EntityCount);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@ namespace Ecs.CSharp.Benchmark
public partial class CreateEntityWithTwoComponents
{
[Context] private readonly FennecsBaseContext _fennecs;

[BenchmarkCategory(Categories.Fennecs)]
[Benchmark]
[Benchmark(Description = "fennecs")]
public void Fennecs()
{
World world = _fennecs.World;

for (int i = 0; i < EntityCount; ++i)
{
world.Spawn().
Add<Component1>().Add<Component2>();
}
world.Entity()
.Add(new Component1())
.Add(new Component2())
.Spawn(EntityCount);
}
}
}
2 changes: 1 addition & 1 deletion source/Ecs.CSharp.Benchmark/Ecs.CSharp.Benchmark.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<PackageReference Include="DefaultEcs" Version="0.17.2" />
<PackageReference Include="DefaultEcs.Analyzer" Version="0.17.0" PrivateAssets="all" />

<PackageReference Include="fennecs" Version="0.1.1-beta" />
<PackageReference Include="fennecs" Version="0.5.4-beta" />

<PackageReference Include="Friflo.Engine.ECS" Version="1.14.0" />

Expand Down
20 changes: 14 additions & 6 deletions source/Ecs.CSharp.Benchmark/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,26 @@

BenchmarkSwitcher benchmark = BenchmarkSwitcher.FromTypes(new[]
{
typeof(CreateEntityWithOneComponent),
typeof(CreateEntityWithTwoComponents),
typeof(CreateEntityWithThreeComponents),

typeof(SystemWithOneComponent),
typeof(SystemWithTwoComponents),
typeof(SystemWithThreeComponents),

typeof(SystemWithTwoComponentsMultipleComposition)
typeof(SystemWithTwoComponentsMultipleComposition),

//Moving lighter tests to the back makes the estimated time display more reliable
typeof(CreateEntityWithOneComponent),
typeof(CreateEntityWithTwoComponents),
typeof(CreateEntityWithThreeComponents),
});

IConfig configuration = DefaultConfig.Instance.WithOptions(ConfigOptions.DisableOptimizationsValidator);

IConfig configuration = DefaultConfig.Instance
.WithOptions(ConfigOptions.DisableOptimizationsValidator)
.WithCapabilityExclusions();

#if RANK_RESULTS
configuration = configuration.WithOrderer(new BenchmarkDotNet.Order.DefaultOrderer(BenchmarkDotNet.Order.SummaryOrderPolicy.FastestToSlowest));
#endif

if (args.Length > 0)
{
Expand Down
Loading