Refactored map selector benchmarks (#914)
This commit is contained in:
parent
2f13dfebed
commit
51169ddbb0
8 changed files with 1880 additions and 669 deletions
|
|
@ -10,6 +10,8 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
|
||||
<PackageReference Include="NetFabric.Hyperlinq" Version="3.0.0-beta48" />
|
||||
<PackageReference Include="StructLinq" Version="0.27.0" />
|
||||
<ProjectReference Include="..\Server\Server.csproj" />
|
||||
<ProjectReference Include="..\UOContent\UOContent.csproj" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
545
Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs
Normal file
545
Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs
Normal file
|
|
@ -0,0 +1,545 @@
|
|||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using NetFabric.Hyperlinq;
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static NetFabric.Hyperlinq.ArrayExtensions;
|
||||
|
||||
namespace Benchmarks.EntitiesSelectors
|
||||
{
|
||||
[SimpleJob(RuntimeMoniker.Net60)]
|
||||
[MemoryDiagnoser]
|
||||
public class MapEntitiesSelectors
|
||||
{
|
||||
private static readonly Sector sector = new();
|
||||
private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) };
|
||||
|
||||
public static Rectangle2D[] BoundsArray() => new[]
|
||||
{
|
||||
new Rectangle2D(70, 70, 100, 100),
|
||||
new Rectangle2D(30, 30, 100, 100),
|
||||
new Rectangle2D(0, 0, 100, 100),
|
||||
};
|
||||
|
||||
[GlobalSetup]
|
||||
public static void Init()
|
||||
{
|
||||
for (int j = 0; j < locations.Length; j++)
|
||||
{
|
||||
Point3D loc = locations[j];
|
||||
|
||||
for (int i = 0; i < 500; ++i)
|
||||
{
|
||||
sector.BItems.Add(new BItem(loc));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 25; ++i)
|
||||
{
|
||||
sector.Mobiles.Add(new Mobile(loc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ParamsSource(nameof(BoundsArray))]
|
||||
public Rectangle2D bounds;
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public IEntity SelectEntitiesFor()
|
||||
{
|
||||
IEntity toRet = null;
|
||||
for (int i = sector.Mobiles.Count - 1; i >= 0; --i)
|
||||
{
|
||||
Mobile mob = sector.Mobiles[i];
|
||||
if (mob is { Deleted: false } tMob && bounds.Contains(mob.Location))
|
||||
{
|
||||
toRet = tMob;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = sector.BItems.Count - 1; i >= 0; --i)
|
||||
{
|
||||
BItem item = sector.BItems[i];
|
||||
if (item is { Deleted: false, Parent: null } tItem && bounds.Contains(item.Location))
|
||||
{
|
||||
toRet = tItem;
|
||||
}
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IEntity SelectEntitiesNew()
|
||||
{
|
||||
IEntity toRet = null;
|
||||
foreach (IEntity e in SelectEntitiesNew(sector, bounds))
|
||||
{
|
||||
toRet = e;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IEntity SelectEntitiesLinq()
|
||||
{
|
||||
IEntity toRet = null;
|
||||
foreach (IEntity e in SelectEntitiesLinq(sector, bounds))
|
||||
{
|
||||
toRet = e;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IEntity SelectMobilesHyperLinq()
|
||||
{
|
||||
IEntity toRet = null;
|
||||
foreach (IEntity e in SelectEntitiesHyperlinq(sector, bounds))
|
||||
{
|
||||
toRet = e;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<IEntity> SelectEntitiesLinq(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
return Enumerable.Empty<IEntity>()
|
||||
.Union(s.Mobiles.Where(o => o is { Deleted: false } && bounds.Contains(o.Location)))
|
||||
.Union(s.BItems.Where(o => o is { Deleted: false, Parent: null } && bounds.Contains(o.Location)));
|
||||
}
|
||||
|
||||
private readonly List<IEntity> entities = new(10);
|
||||
|
||||
public IEnumerable<IEntity> SelectEntitiesNew(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
entities.Clear();
|
||||
entities.EnsureCapacity(s.Mobiles.Count + s.BItems.Count);
|
||||
|
||||
for (int i = s.Mobiles.Count - 1, j = s.BItems.Count - 1; i >= 0 || j >= 0; --i, --j)
|
||||
{
|
||||
if (j >= 0)
|
||||
{
|
||||
BItem BItem = s.BItems[j];
|
||||
if (BItem is { Deleted: false, Parent: null } && bounds.Contains(BItem.Location))
|
||||
{
|
||||
entities.Add(BItem);
|
||||
}
|
||||
}
|
||||
if (i >= 0)
|
||||
{
|
||||
Mobile mob = s.Mobiles[i];
|
||||
if (mob is { Deleted: false } && bounds.Contains(mob.Location))
|
||||
{
|
||||
entities.Add(mob);
|
||||
}
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public IEnumerable<IEntity> SelectEntitiesHyperlinq(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
ArraySegmentWhereSelectEnumerable<Mobile, IEntity, MobileWhereHyper, SelectHyper<Mobile, IEntity>> mobiles =
|
||||
s.Mobiles.AsValueEnumerable().Where(new MobileWhereHyper(bounds)).Select<IEntity, SelectHyper<Mobile, IEntity>>();
|
||||
|
||||
ArraySegmentWhereSelectEnumerable<BItem, IEntity, BItemWhereHyper, SelectHyper<BItem, IEntity>> items =
|
||||
s.BItems.AsValueEnumerable().Where(new BItemWhereHyper(bounds)).Select<IEntity, SelectHyper<BItem, IEntity>>();
|
||||
|
||||
return mobiles.Concat(items);
|
||||
}
|
||||
}
|
||||
|
||||
public class BItem : IPoint3D, IEntity
|
||||
{
|
||||
public object Parent { get; set; } = null;
|
||||
|
||||
public bool Deleted { get; set; } = false;
|
||||
|
||||
public int Z { get; set; } = 1;
|
||||
|
||||
public int X { get; set; } = 1;
|
||||
|
||||
public int Y { get; set; } = 1;
|
||||
|
||||
public Serial Serial => throw new NotImplementedException();
|
||||
|
||||
public Point3D Location { get; }
|
||||
public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public Region Region => throw new NotImplementedException();
|
||||
|
||||
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public int TypeRef => throw new NotImplementedException();
|
||||
|
||||
Point3D IEntity.Location => Location;
|
||||
|
||||
Map IEntity.Map => throw new NotImplementedException();
|
||||
|
||||
int IPoint3D.Z => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.X => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.Y => throw new NotImplementedException();
|
||||
|
||||
DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
int ISerializable.TypeRef => throw new NotImplementedException();
|
||||
|
||||
Serial ISerializable.Serial => throw new NotImplementedException();
|
||||
|
||||
bool ISerializable.Deleted => throw new NotImplementedException();
|
||||
|
||||
public BItem(Point3D location)
|
||||
{
|
||||
Location = location;
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ProcessDelta()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnStatsQuery(Server.Mobile m)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void InvalidateProperties()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(IEntity other)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveBItem(BItem BItem)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IEntity.MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IEntity.ProcessDelta()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool IEntity.InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool IEntity.InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveItem(Item item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class Mobile : IPoint3D, IEntity
|
||||
{
|
||||
public bool Deleted { get; set; } = false;
|
||||
|
||||
public int Z { get; set; } = 1;
|
||||
|
||||
public int X { get; set; } = 1;
|
||||
|
||||
public int Y { get; set; } = 1;
|
||||
|
||||
public Serial Serial => throw new NotImplementedException();
|
||||
|
||||
public Point3D Location { get; }
|
||||
public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public Region Region => throw new NotImplementedException();
|
||||
|
||||
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public int Hue { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public Direction Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public int TypeRef => throw new NotImplementedException();
|
||||
|
||||
Point3D IEntity.Location => Location;
|
||||
|
||||
Map IEntity.Map => throw new NotImplementedException();
|
||||
|
||||
int IPoint3D.Z => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.X => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.Y => throw new NotImplementedException();
|
||||
|
||||
DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
int ISerializable.TypeRef => throw new NotImplementedException();
|
||||
|
||||
Serial ISerializable.Serial => throw new NotImplementedException();
|
||||
|
||||
bool ISerializable.Deleted => throw new NotImplementedException();
|
||||
|
||||
public Mobile(Point3D location)
|
||||
{
|
||||
Location = location;
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ProcessDelta()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnStatsQuery(Server.Mobile m)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void InvalidateProperties()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(IEntity other)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveBItem(BItem BItem)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IEntity.MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IEntity.ProcessDelta()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool IEntity.InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool IEntity.InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveItem(Item item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class Sector
|
||||
{
|
||||
public List<BItem> BItems { get; set; } = new List<BItem>();
|
||||
public List<Mobile> Mobiles { get; set; } = new List<Mobile>();
|
||||
}
|
||||
|
||||
public struct BItemWhereHyper : NetFabric.Hyperlinq.IFunction<BItem, bool>
|
||||
{
|
||||
private readonly Rectangle2D bounds;
|
||||
|
||||
public BItemWhereHyper(Rectangle2D bounds)
|
||||
{
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
public bool Invoke(BItem element)
|
||||
{
|
||||
return element is { Deleted: false, Parent: null } && bounds.Contains(element.Location);
|
||||
}
|
||||
}
|
||||
|
||||
public struct MobileWhereHyper : NetFabric.Hyperlinq.IFunction<Mobile, bool>
|
||||
{
|
||||
private readonly Rectangle2D bounds;
|
||||
|
||||
public MobileWhereHyper(Rectangle2D bounds)
|
||||
{
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
public bool Invoke(Mobile element)
|
||||
{
|
||||
return element is { Deleted: false } && bounds.Contains(element.Location);
|
||||
}
|
||||
}
|
||||
|
||||
public struct SelectHyper<TSource, TDest> : NetFabric.Hyperlinq.IFunction<TSource, TDest> where TSource : TDest
|
||||
{
|
||||
public TDest Invoke(TSource arg)
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
403
Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs
Normal file
403
Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using NetFabric.Hyperlinq;
|
||||
using Server;
|
||||
using StructLinq;
|
||||
using StructLinq.Array;
|
||||
using StructLinq.List;
|
||||
using StructLinq.Select;
|
||||
using StructLinq.Where;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static NetFabric.Hyperlinq.ArrayExtensions;
|
||||
|
||||
namespace Benchmarks.ItemSelectors
|
||||
{
|
||||
[SimpleJob(RuntimeMoniker.Net60)]
|
||||
[MemoryDiagnoser]
|
||||
public class MapItemSelectors
|
||||
{
|
||||
private static readonly Sector sector = new();
|
||||
private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) };
|
||||
|
||||
public static Rectangle2D[] BoundsArray() => new[]
|
||||
{
|
||||
new Rectangle2D(70, 70, 100, 100),
|
||||
new Rectangle2D(30, 30, 100, 100),
|
||||
new Rectangle2D(0, 0, 100, 100),
|
||||
};
|
||||
|
||||
[GlobalSetup]
|
||||
public static void Init()
|
||||
{
|
||||
for (int j = 0; j < locations.Length; j++)
|
||||
{
|
||||
Point3D loc = locations[j];
|
||||
|
||||
for (int i = 0; i < 500; ++i)
|
||||
{
|
||||
sector.BItems.Add(new BItemDerived(loc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ParamsSource(nameof(BoundsArray))]
|
||||
public Rectangle2D bounds;
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public BItemDerived SelectBItemsFor()
|
||||
{
|
||||
BItemDerived toRet = null;
|
||||
for (int i = sector.BItems.Count - 1; i >= 0; --i)
|
||||
{
|
||||
BItem BItem = sector.BItems[i];
|
||||
if (BItem is BItemDerived { Deleted: false, Parent: null } tItem && bounds.Contains(BItem.Location))
|
||||
{
|
||||
toRet = tItem;
|
||||
}
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public BItemDerived SelectBItemsNew()
|
||||
{
|
||||
BItemDerived toRet = null;
|
||||
foreach (BItemDerived i in SelectBItems<BItemDerived>(sector, bounds))
|
||||
{
|
||||
toRet = i;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public BItemDerived SelectBItemsLinq()
|
||||
{
|
||||
BItemDerived toRet = null;
|
||||
foreach (BItemDerived i in SelectBItemsLinq<BItemDerived>(sector, bounds))
|
||||
{
|
||||
toRet = i;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public BItemDerived SelectBItemsLinqStruct()
|
||||
{
|
||||
BItemDerived toRet = null;
|
||||
foreach (BItemDerived i in SelectBItemsLinqStruct<BItemDerived>(sector, bounds))
|
||||
{
|
||||
toRet = i;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public BItemDerived SelectBItemsLinqStructInterface()
|
||||
{
|
||||
BItemDerived toRet = null;
|
||||
IEnumerable<BItemDerived> enumerable = SelectBItemsLinqStruct<BItemDerived>(sector, bounds).ToEnumerable();
|
||||
|
||||
foreach (BItemDerived i in enumerable)
|
||||
{
|
||||
toRet = i;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public BItemDerived SelectBItemsHyperLinq()
|
||||
{
|
||||
BItemDerived toRet = null;
|
||||
foreach (BItemDerived i in SelectBItemsHyperlinq<BItemDerived>(sector, bounds))
|
||||
{
|
||||
toRet = i;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public BItemDerived SelectBItemsHyperLinqInterface()
|
||||
{
|
||||
BItemDerived toRet = null;
|
||||
IEnumerable<BItemDerived> enumerable = SelectBItemsHyperlinq<BItemDerived>(sector, bounds);
|
||||
|
||||
foreach (BItemDerived i in enumerable)
|
||||
{
|
||||
toRet = i;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public BItemDerived SelectBItemsHyperLinqArrayPool()
|
||||
{
|
||||
BItemDerived toRet = null;
|
||||
using Lease<BItemDerived> lease = SelectBItemsHyperlinq<BItemDerived>(sector, bounds).ToArray(ArrayPool<BItemDerived>.Shared);
|
||||
|
||||
foreach (BItemDerived i in lease)
|
||||
{
|
||||
toRet = i;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectBItemsLinq<T>(Sector s, Rectangle2D bounds) where T : BItem
|
||||
{
|
||||
return s.BItems.OfType<T>().Where(o => o is { Deleted: false, Parent: null } && bounds.Contains(o.Location));
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectBItems<T>(Sector s, Rectangle2D bounds) where T : BItem
|
||||
{
|
||||
List<BItem> items = s.BItems;
|
||||
List<T> entities = new(items.Count);
|
||||
|
||||
for (int i = items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (items[i] is T { Deleted: false, Parent: null } tItem && bounds.Contains(tItem.Location))
|
||||
{
|
||||
entities.Add(tItem);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public SelectEnumerable<BItem, T, WhereEnumerable<BItem, ListEnumerable<BItem>, ArrayStructEnumerator<BItem>, BItemWhere<T>>,
|
||||
WhereEnumerator<BItem, ArrayStructEnumerator<BItem>, BItemWhere<T>>, BItemSelect<T>>
|
||||
SelectBItemsLinqStruct<T>(Sector s, Rectangle2D bounds) where T : BItem
|
||||
{
|
||||
BItemWhere<T> bitemWhere = new(bounds);
|
||||
BItemSelect<T> bitemSelect = new();
|
||||
|
||||
return s.BItems.ToStructEnumerable()
|
||||
.Where(ref bitemWhere, x => x)
|
||||
.Select(ref bitemSelect, x => x, x => x);
|
||||
}
|
||||
|
||||
public ArraySegmentWhereSelectEnumerable<BItem, T, BItemWhereHyper<T>, SelectHyper<BItem, T>>
|
||||
SelectBItemsHyperlinq<T>(Sector s, Rectangle2D bounds) where T : BItem
|
||||
{
|
||||
return s.BItems.AsValueEnumerable()
|
||||
.Where(new BItemWhereHyper<T>(bounds))
|
||||
.Select<T, SelectHyper<BItem, T>>();
|
||||
}
|
||||
}
|
||||
|
||||
public class BItem : IPoint3D, IEntity
|
||||
{
|
||||
public object Parent { get; set; } = null;
|
||||
|
||||
public bool Deleted { get; set; } = false;
|
||||
|
||||
public int Z { get; set; } = 1;
|
||||
|
||||
public int X { get; set; } = 1;
|
||||
|
||||
public int Y { get; set; } = 1;
|
||||
|
||||
public Serial Serial => throw new NotImplementedException();
|
||||
|
||||
public Point3D Location { get; }
|
||||
|
||||
public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public Region Region => throw new NotImplementedException();
|
||||
|
||||
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public int TypeRef => throw new NotImplementedException();
|
||||
|
||||
Point3D IEntity.Location => Location;
|
||||
|
||||
int IPoint3D.Z => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.X => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.Y => throw new NotImplementedException();
|
||||
|
||||
DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
int ISerializable.TypeRef => throw new NotImplementedException();
|
||||
|
||||
Serial ISerializable.Serial => throw new NotImplementedException();
|
||||
|
||||
bool ISerializable.Deleted => throw new NotImplementedException();
|
||||
|
||||
public BItem(Point3D location)
|
||||
{
|
||||
Location = location;
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ProcessDelta()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnStatsQuery(Server.Mobile m)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void InvalidateProperties()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(IEntity other)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveBItem(BItem BItem)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveItem(Item item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class BItemDerived : BItem
|
||||
{
|
||||
public BItemDerived(Point3D location) : base(location) { }
|
||||
}
|
||||
|
||||
public class Sector
|
||||
{
|
||||
public List<BItem> BItems { get; set; } = new List<BItem>();
|
||||
}
|
||||
|
||||
public struct BItemWhere<T> : StructLinq.IFunction<BItem, bool> where T : BItem
|
||||
{
|
||||
private readonly Rectangle2D bounds;
|
||||
|
||||
public BItemWhere(Rectangle2D bounds)
|
||||
{
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
public bool Eval(BItem element)
|
||||
{
|
||||
return element is T { Deleted: false, Parent: null } && bounds.Contains(element.Location);
|
||||
}
|
||||
}
|
||||
|
||||
public struct BItemSelect<T> : StructLinq.IFunction<BItem, T> where T : BItem
|
||||
{
|
||||
public T Eval(BItem element)
|
||||
{
|
||||
return (T)element;
|
||||
}
|
||||
}
|
||||
|
||||
public struct BItemWhereHyper<T> : NetFabric.Hyperlinq.IFunction<BItem, bool> where T : BItem
|
||||
{
|
||||
private readonly Rectangle2D bounds;
|
||||
|
||||
public BItemWhereHyper(Rectangle2D bounds)
|
||||
{
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
public bool Invoke(BItem element)
|
||||
{
|
||||
return element is T { Deleted: false, Parent: null } && bounds.Contains(element.Location);
|
||||
}
|
||||
}
|
||||
|
||||
public struct SelectHyper<TSource, TDest> : NetFabric.Hyperlinq.IFunction<TSource, TDest> where TDest : TSource
|
||||
{
|
||||
public TDest Invoke(TSource arg)
|
||||
{
|
||||
return (TDest)arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
255
Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs
Normal file
255
Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using NetFabric.Hyperlinq;
|
||||
using Server;
|
||||
using StructLinq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static NetFabric.Hyperlinq.ArrayExtensions;
|
||||
|
||||
namespace Benchmarks.MobileSelectors
|
||||
{
|
||||
[SimpleJob(RuntimeMoniker.Net60)]
|
||||
[MemoryDiagnoser]
|
||||
public class MapMobileSelectors
|
||||
{
|
||||
private static readonly Sector sector = new();
|
||||
private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) };
|
||||
|
||||
public static Rectangle2D[] BoundsArray() => new[]
|
||||
{
|
||||
new Rectangle2D(70, 70, 100, 100),
|
||||
new Rectangle2D(30, 30, 100, 100),
|
||||
new Rectangle2D(0, 0, 100, 100),
|
||||
};
|
||||
|
||||
[GlobalSetup]
|
||||
public static void Init()
|
||||
{
|
||||
for (int j = 0; j < locations.Length; j++)
|
||||
{
|
||||
Point3D loc = locations[j];
|
||||
|
||||
for (int i = 0; i < 500; ++i)
|
||||
{
|
||||
sector.Mobiles.Add(new MobileDerived(loc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ParamsSource(nameof(BoundsArray))]
|
||||
public Rectangle2D bounds;
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public MobileDerived SelectMobilesFor()
|
||||
{
|
||||
MobileDerived toRet = null;
|
||||
for (int i = sector.Mobiles.Count - 1; i >= 0; --i)
|
||||
{
|
||||
Mobile mob = sector.Mobiles[i];
|
||||
if (mob is MobileDerived { Deleted: false } tMob && bounds.Contains(mob.Location))
|
||||
{
|
||||
toRet = tMob;
|
||||
}
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public MobileDerived SelectMobilesNew()
|
||||
{
|
||||
MobileDerived toRet = null;
|
||||
foreach (MobileDerived m in SelectMobiles<MobileDerived>(sector, bounds))
|
||||
{
|
||||
toRet = m;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public MobileDerived SelectMobilesLinq()
|
||||
{
|
||||
MobileDerived toRet = null;
|
||||
foreach (MobileDerived m in SelectMobilesLinq<MobileDerived>(sector, bounds))
|
||||
{
|
||||
toRet = m;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public MobileDerived SelectMobilesHyperLinq()
|
||||
{
|
||||
MobileDerived toRet = null;
|
||||
foreach (MobileDerived m in SelectMobilesHyperlinq<MobileDerived>(sector, bounds))
|
||||
{
|
||||
toRet = m;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectMobilesLinq<T>(Sector s, Rectangle2D bounds) where T : Mobile
|
||||
{
|
||||
return s.Mobiles.OfType<T>().Where(o => o is { Deleted: false } && bounds.Contains(o.Location));
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectMobiles<T>(Sector s, Rectangle2D bounds) where T : Mobile
|
||||
{
|
||||
List<Mobile> mobiles = s.Mobiles;
|
||||
List<T> entities = new(mobiles.Count);
|
||||
|
||||
for (int i = mobiles.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (mobiles[i] is T { Deleted: false } tMob && bounds.Contains(tMob.Location))
|
||||
{
|
||||
entities.Add(tMob);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public ArraySegmentWhereSelectEnumerable<Mobile, T, MobileWhereHyper<T>, SelectHyper<Mobile, T>>
|
||||
SelectMobilesHyperlinq<T>(Sector s, Rectangle2D bounds) where T : Mobile
|
||||
{
|
||||
return s.Mobiles.AsValueEnumerable()
|
||||
.Where(new MobileWhereHyper<T>(bounds))
|
||||
.Select<T, SelectHyper<Mobile, T>>();
|
||||
}
|
||||
}
|
||||
|
||||
public class Mobile : IPoint3D, IEntity
|
||||
{
|
||||
public bool Deleted { get; set; } = false;
|
||||
|
||||
public int Z { get; set; } = 1;
|
||||
|
||||
public int X { get; set; } = 1;
|
||||
|
||||
public int Y { get; set; } = 1;
|
||||
|
||||
public Serial Serial => throw new NotImplementedException();
|
||||
|
||||
public Point3D Location { get; }
|
||||
|
||||
public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public Region Region => throw new NotImplementedException();
|
||||
|
||||
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public int Hue { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public Direction Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public int TypeRef => throw new NotImplementedException();
|
||||
|
||||
int IPoint3D.Z => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.X => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.Y => throw new NotImplementedException();
|
||||
|
||||
DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
int ISerializable.TypeRef => throw new NotImplementedException();
|
||||
|
||||
Serial ISerializable.Serial => throw new NotImplementedException();
|
||||
|
||||
bool ISerializable.Deleted => throw new NotImplementedException();
|
||||
|
||||
public Mobile(Point3D location)
|
||||
{
|
||||
Location = location;
|
||||
}
|
||||
|
||||
public void MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ProcessDelta()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveItem(Item item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class MobileDerived : Mobile
|
||||
{
|
||||
public MobileDerived(Point3D location) : base(location) { }
|
||||
}
|
||||
|
||||
public class Sector
|
||||
{
|
||||
public List<Mobile> Mobiles { get; set; } = new List<Mobile>();
|
||||
}
|
||||
|
||||
public struct MobileWhereHyper<T> : NetFabric.Hyperlinq.IFunction<Mobile, bool> where T : Mobile
|
||||
{
|
||||
private readonly Rectangle2D bounds;
|
||||
|
||||
public MobileWhereHyper(Rectangle2D bounds)
|
||||
{
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
public bool Invoke(Mobile element)
|
||||
{
|
||||
return element is T { Deleted: false } && bounds.Contains(element.Location);
|
||||
}
|
||||
}
|
||||
|
||||
public struct SelectHyper<TSource, TDest> : NetFabric.Hyperlinq.IFunction<TSource, TDest> where TDest : TSource
|
||||
{
|
||||
public TDest Invoke(TSource arg)
|
||||
{
|
||||
return (TDest)arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
311
Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs
Normal file
311
Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using NetFabric.Hyperlinq;
|
||||
using Server;
|
||||
using StructLinq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static NetFabric.Hyperlinq.ArrayExtensions;
|
||||
|
||||
namespace Benchmarks.MultiSelectors
|
||||
{
|
||||
[SimpleJob(RuntimeMoniker.Net60)]
|
||||
[MemoryDiagnoser]
|
||||
public class MapMultiSelectors
|
||||
{
|
||||
private static readonly Sector sector = new();
|
||||
private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) };
|
||||
|
||||
public static Rectangle2D[] BoundsArray() => new[]
|
||||
{
|
||||
new Rectangle2D(70, 70, 100, 100),
|
||||
new Rectangle2D(30, 30, 100, 100),
|
||||
new Rectangle2D(0, 0, 100, 100),
|
||||
};
|
||||
|
||||
[GlobalSetup]
|
||||
public static void Init()
|
||||
{
|
||||
for (int j = 0; j < locations.Length; j++)
|
||||
{
|
||||
Point3D loc = locations[j];
|
||||
|
||||
for (int i = 0; i < 25; ++i)
|
||||
{
|
||||
sector.Multis.Add(new BaseMulti(loc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ParamsSource(nameof(BoundsArray))]
|
||||
public Rectangle2D bounds;
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public BaseMulti SelectMultiFor()
|
||||
{
|
||||
BaseMulti toRet = null;
|
||||
for (int i = sector.Multis.Count - 1; i >= 0; --i)
|
||||
{
|
||||
BaseMulti multi = sector.Multis[i];
|
||||
if (multi is { Deleted: false } tMulti && bounds.Contains(multi.Location))
|
||||
{
|
||||
toRet = tMulti;
|
||||
}
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public BaseMulti SelectMultiNew()
|
||||
{
|
||||
BaseMulti toRet = null;
|
||||
foreach (BaseMulti m in SelectMultiNew(sector, bounds))
|
||||
{
|
||||
toRet = m;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public BaseMulti SelectMultiLinq()
|
||||
{
|
||||
BaseMulti toRet = null;
|
||||
foreach (BaseMulti m in SelectMultiLinq(sector, bounds))
|
||||
{
|
||||
toRet = m;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public BaseMulti SelectMultiHyperLinq()
|
||||
{
|
||||
BaseMulti toRet = null;
|
||||
foreach (BaseMulti m in SelectMultiHyperlinq(sector, bounds))
|
||||
{
|
||||
toRet = m;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
public IEnumerable<BaseMulti> SelectMultiLinq(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
return s.Multis.Where(o => o is { Deleted: false } && bounds.Contains(o.Location));
|
||||
}
|
||||
|
||||
public IEnumerable<BaseMulti> SelectMultiNew(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
List<BaseMulti> entities = new(s.Multis.Count);
|
||||
|
||||
for (int i = s.Multis.Count - 1; i >= 0; --i)
|
||||
{
|
||||
BaseMulti multiItem = s.Multis[i];
|
||||
if (multiItem is { Deleted: false } && bounds.Contains(multiItem.Location))
|
||||
{
|
||||
entities.Add(multiItem);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public ArraySegmentWhereEnumerable<BaseMulti, MultiWhereHyper>
|
||||
SelectMultiHyperlinq(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
return s.Multis.AsValueEnumerable().Where(new MultiWhereHyper(bounds));
|
||||
}
|
||||
}
|
||||
|
||||
public class BItem : IPoint3D, IEntity
|
||||
{
|
||||
public object Parent { get; set; } = null;
|
||||
|
||||
public bool Deleted { get; set; } = false;
|
||||
|
||||
public int Z { get; set; } = 1;
|
||||
|
||||
public int X { get; set; } = 1;
|
||||
|
||||
public int Y { get; set; } = 1;
|
||||
|
||||
public Serial Serial => throw new NotImplementedException();
|
||||
|
||||
public Point3D Location { get; }
|
||||
|
||||
public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public Region Region => throw new NotImplementedException();
|
||||
|
||||
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public int TypeRef => throw new NotImplementedException();
|
||||
|
||||
int IPoint3D.Z => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.X => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.Y => throw new NotImplementedException();
|
||||
|
||||
DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
int ISerializable.TypeRef => throw new NotImplementedException();
|
||||
|
||||
Serial ISerializable.Serial => throw new NotImplementedException();
|
||||
|
||||
bool ISerializable.Deleted => throw new NotImplementedException();
|
||||
|
||||
public BItem(Point3D location)
|
||||
{
|
||||
Location = location;
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ProcessDelta()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnStatsQuery(Server.Mobile m)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void InvalidateProperties()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(IEntity other)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveBItem(BItem BItem)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveItem(Item item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class BaseMulti : BItem
|
||||
{
|
||||
public MultiComponentList Components = MultiComponentList.Empty;
|
||||
|
||||
public BaseMulti(Point3D location) : base(location)
|
||||
{
|
||||
for (int i = 0; i < 20; ++i)
|
||||
{
|
||||
for (int j = 0; j < 20; ++j)
|
||||
{
|
||||
for (int z = 0; z < 20; ++z)
|
||||
{
|
||||
Components.Add(123, i, j, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Sector
|
||||
{
|
||||
public List<BaseMulti> Multis { get; set; } = new List<BaseMulti>();
|
||||
}
|
||||
|
||||
public struct MultiWhereHyper : NetFabric.Hyperlinq.IFunction<BaseMulti, bool>
|
||||
{
|
||||
private readonly Rectangle2D bounds;
|
||||
|
||||
public MultiWhereHyper(Rectangle2D bounds)
|
||||
{
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
public bool Invoke(BaseMulti element)
|
||||
{
|
||||
return element is { Deleted: false } && bounds.Contains(element.Location);
|
||||
}
|
||||
}
|
||||
}
|
||||
352
Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs
Normal file
352
Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using NetFabric.Hyperlinq;
|
||||
using Server;
|
||||
using StructLinq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Benchmarks.MultiTilesSelectors
|
||||
{
|
||||
[SimpleJob(RuntimeMoniker.Net60)]
|
||||
[MemoryDiagnoser]
|
||||
public class MapMultiTilesSelectors
|
||||
{
|
||||
private static readonly Sector sector = new();
|
||||
private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) };
|
||||
|
||||
public static Rectangle2D[] BoundsArray() => new[]
|
||||
{
|
||||
new Rectangle2D(70, 70, 100, 100),
|
||||
new Rectangle2D(30, 30, 100, 100),
|
||||
new Rectangle2D(0, 0, 100, 100),
|
||||
};
|
||||
|
||||
[GlobalSetup]
|
||||
public static void Init()
|
||||
{
|
||||
for (int j = 0; j < locations.Length; j++)
|
||||
{
|
||||
Point3D loc = locations[j];
|
||||
|
||||
for (int i = 0; i < 25; ++i)
|
||||
{
|
||||
sector.Multis.Add(new BaseMulti(loc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ParamsSource(nameof(BoundsArray))]
|
||||
public Rectangle2D bounds;
|
||||
|
||||
[Benchmark]
|
||||
public int SelectMultiTilesNew()
|
||||
{
|
||||
int toRet = 0;
|
||||
|
||||
foreach (StaticTile[] tiles in SelectMultiTilesNew(sector, bounds))
|
||||
{
|
||||
for (int i = 0; i < tiles.Length; ++i)
|
||||
{
|
||||
toRet = tiles[i].ID;
|
||||
}
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public int SelectMultiTilesLinq()
|
||||
{
|
||||
int toRet = 0;
|
||||
|
||||
foreach (StaticTile[] tiles in SelectMultiTilesLinq(sector, bounds))
|
||||
{
|
||||
for (int i = 0; i < tiles.Length; ++i)
|
||||
{
|
||||
toRet = tiles[i].ID;
|
||||
}
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
public IEnumerable<StaticTile[]> SelectMultiTilesLinq(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
foreach (var o in s.Multis.Where(o => o != null && !o.Deleted))
|
||||
{
|
||||
var c = o.Components;
|
||||
|
||||
int x, y, xo, yo;
|
||||
StaticTile[] t, r;
|
||||
|
||||
for (x = bounds.Start.X; x < bounds.End.X; x++)
|
||||
{
|
||||
xo = x - (o.X + c.Min.X);
|
||||
|
||||
if (xo < 0 || xo >= c.Width)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (y = bounds.Start.Y; y < bounds.End.Y; y++)
|
||||
{
|
||||
yo = y - (o.Y + c.Min.Y);
|
||||
|
||||
if (yo < 0 || yo >= c.Height)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
t = c.Tiles[xo][yo];
|
||||
|
||||
if (t.Length <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
r = new StaticTile[t.Length];
|
||||
|
||||
for (var i = 0; i < t.Length; i++)
|
||||
{
|
||||
r[i] = t[i];
|
||||
r[i].Z += o.Z;
|
||||
}
|
||||
|
||||
yield return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<StaticTile[]> SelectMultiTilesNew(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
List<BaseMulti> multis = s.Multis;
|
||||
|
||||
for (int l = multis.Count - 1; l >= 0; --l)
|
||||
{
|
||||
if (multis[l] is not { Deleted: false } o)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
MultiComponentList c = o.Components;
|
||||
|
||||
int x, y, xo, yo;
|
||||
StaticTile[] t, r;
|
||||
|
||||
for (x = bounds.Start.X; x < bounds.End.X; x++)
|
||||
{
|
||||
xo = x - (o.X + c.Min.X);
|
||||
|
||||
if (xo < 0 || xo >= c.Width)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (y = bounds.Start.Y; y < bounds.End.Y; y++)
|
||||
{
|
||||
yo = y - (o.Y + c.Min.Y);
|
||||
|
||||
if (yo < 0 || yo >= c.Height)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
t = c.Tiles[xo][yo];
|
||||
|
||||
if (t.Length <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
r = new StaticTile[t.Length];
|
||||
|
||||
for (var i = 0; i < t.Length; i++)
|
||||
{
|
||||
r[i] = t[i];
|
||||
r[i].Z += o.Z;
|
||||
}
|
||||
|
||||
yield return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BItem : IPoint3D, IEntity
|
||||
{
|
||||
public object Parent { get; set; } = null;
|
||||
|
||||
public bool Deleted { get; set; } = false;
|
||||
|
||||
public int Z { get; set; } = 1;
|
||||
|
||||
public int X { get; set; } = 1;
|
||||
|
||||
public int Y { get; set; } = 1;
|
||||
|
||||
public Serial Serial => throw new NotImplementedException();
|
||||
|
||||
public Point3D Location { get; }
|
||||
|
||||
public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public Region Region => throw new NotImplementedException();
|
||||
|
||||
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public int TypeRef => throw new NotImplementedException();
|
||||
|
||||
int IPoint3D.Z => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.X => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.Y => throw new NotImplementedException();
|
||||
|
||||
DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
int ISerializable.TypeRef => throw new NotImplementedException();
|
||||
|
||||
Serial ISerializable.Serial => throw new NotImplementedException();
|
||||
|
||||
bool ISerializable.Deleted => throw new NotImplementedException();
|
||||
|
||||
public BItem(Point3D location)
|
||||
{
|
||||
Location = location;
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ProcessDelta()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnStatsQuery(Server.Mobile m)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void InvalidateProperties()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(IEntity other)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveBItem(BItem BItem)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveItem(Item item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class BaseMulti : BItem
|
||||
{
|
||||
public MultiComponentList Components = MultiComponentList.Empty;
|
||||
|
||||
public BaseMulti(Point3D location) : base(location)
|
||||
{
|
||||
for (int i = 0; i < 20; ++i)
|
||||
{
|
||||
for (int j = 0; j < 20; ++j)
|
||||
{
|
||||
for (int z = 0; z < 20; ++z)
|
||||
{
|
||||
Components.Add(123, i, j, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Sector
|
||||
{
|
||||
public List<BaseMulti> Multis { get; set; } = new List<BaseMulti>();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,665 +0,0 @@
|
|||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Benchmarks
|
||||
{
|
||||
[SimpleJob(RuntimeMoniker.NetCoreApp50)]
|
||||
public class MapSelectors
|
||||
{
|
||||
static readonly Sector sector = new Sector();
|
||||
static Server.Rectangle2D bounds = new Server.Rectangle2D(0, 0, 100, 100);
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
for (int i = 0; i < 50; ++i)
|
||||
{
|
||||
sector.Multis.Add(new BaseMulti());
|
||||
}
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
{
|
||||
sector.BItems.Add(new BItem());
|
||||
}
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
{
|
||||
sector.Mobiles.Add(new Mobile());
|
||||
}
|
||||
}
|
||||
|
||||
#region MultiTiles
|
||||
[Benchmark]
|
||||
public void SelectMultiTilesNew()
|
||||
{
|
||||
foreach(StaticTile[] tiles in SelectMultiTiles(sector, bounds))
|
||||
{
|
||||
for(int i = 0; i < tiles.Length; ++i)
|
||||
{
|
||||
int id = tiles[i].ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void SelectMultiTilesLinq()
|
||||
{
|
||||
foreach(StaticTile[] tiles in SelectMultiTilesLinq(sector, bounds))
|
||||
{
|
||||
for(int i = 0; i < tiles.Length; ++i)
|
||||
{
|
||||
int id = tiles[i].ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<StaticTile[]> SelectMultiTilesLinq(Sector s, Server.Rectangle2D bounds)
|
||||
{
|
||||
foreach (var o in s.Multis.Where(o => o != null && !o.Deleted))
|
||||
{
|
||||
var c = o.Components;
|
||||
|
||||
int x, y, xo, yo;
|
||||
StaticTile[] t, r;
|
||||
|
||||
for (x = bounds.Start.X; x < bounds.End.X; x++)
|
||||
{
|
||||
xo = x - (o.X + c.Min.X);
|
||||
|
||||
if (xo < 0 || xo >= c.Width)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (y = bounds.Start.Y; y < bounds.End.Y; y++)
|
||||
{
|
||||
yo = y - (o.Y + c.Min.Y);
|
||||
|
||||
if (yo < 0 || yo >= c.Height)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
t = c.Tiles[xo][yo];
|
||||
|
||||
if (t.Length <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
r = new StaticTile[t.Length];
|
||||
|
||||
for (var i = 0; i < t.Length; i++)
|
||||
{
|
||||
r[i] = t[i];
|
||||
r[i].Z += o.Z;
|
||||
}
|
||||
|
||||
yield return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<StaticTile[]> SelectMultiTiles(Sector s, Server.Rectangle2D bounds)
|
||||
{
|
||||
for (int l = s.Multis.Count - 1; l >= 0; --l)
|
||||
{
|
||||
BaseMulti o = s.Multis[l];
|
||||
if (o != null && !o.Deleted)
|
||||
{
|
||||
MultiComponentList c = o.Components;
|
||||
|
||||
int x, y, xo, yo;
|
||||
StaticTile[] t, r;
|
||||
|
||||
for (x = bounds.Start.X; x < bounds.End.X; x++)
|
||||
{
|
||||
xo = x - (o.X + c.Min.X);
|
||||
|
||||
if (xo < 0 || xo >= c.Width)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (y = bounds.Start.Y; y < bounds.End.Y; y++)
|
||||
{
|
||||
yo = y - (o.Y + c.Min.Y);
|
||||
|
||||
if (yo < 0 || yo >= c.Height)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
t = c.Tiles[xo][yo];
|
||||
|
||||
if (t.Length <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
r = new StaticTile[t.Length];
|
||||
|
||||
for (var i = 0; i < t.Length; i++)
|
||||
{
|
||||
r[i] = t[i];
|
||||
r[i].Z += o.Z;
|
||||
}
|
||||
|
||||
yield return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Multis
|
||||
[Benchmark]
|
||||
public void SelectMultisNew()
|
||||
{
|
||||
SelectMultis(sector, bounds);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void SelectMultisLinq()
|
||||
{
|
||||
SelectMultisLinq(sector, bounds);
|
||||
}
|
||||
|
||||
public IEnumerable<BaseMulti> SelectMultisLinq(Sector s, Server.Rectangle2D bounds)
|
||||
{
|
||||
return s.Multis.Where(o => o != null && !o.Deleted && bounds.Contains(o.Location));
|
||||
}
|
||||
|
||||
public IEnumerable<BaseMulti> SelectMultis(Sector s, Server.Rectangle2D bounds)
|
||||
{
|
||||
List<BaseMulti> entities = new List<BaseMulti>(s.Multis.Count);
|
||||
for (int i = s.Multis.Count - 1; i >= 0; --i)
|
||||
{
|
||||
BaseMulti BItem = s.Multis[i];
|
||||
if (BItem != null && !BItem.Deleted && bounds.Contains(BItem.Location))
|
||||
entities.Add(BItem);
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region BItems
|
||||
[Benchmark]
|
||||
public void SelectBItemsNew()
|
||||
{
|
||||
SelectBItems<BItem>(sector, bounds);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void SelectBItemsLinq()
|
||||
{
|
||||
SelectBItemsLinq<BItem>(sector, bounds);
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectBItemsLinq<T>(Sector s, Server.Rectangle2D bounds) where T : BItem
|
||||
{
|
||||
return s.BItems.OfType<T>().Where(o => o != null && !o.Deleted && o.Parent == null && bounds.Contains(o.Location));
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectBItems<T>(Sector s, Server.Rectangle2D bounds) where T : BItem
|
||||
{
|
||||
List<T> entities = new List<T>(s.BItems.Count);
|
||||
Type type = typeof(T);
|
||||
for (int i = s.BItems.Count - 1; i >= 0; --i)
|
||||
{
|
||||
BItem BItem = s.BItems[i];
|
||||
if (BItem != null && !BItem.Deleted && BItem.Parent == null && bounds.Contains(BItem.Location) && type.IsAssignableFrom(BItem.GetType()))
|
||||
entities.Add(BItem as T);
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Mobiles
|
||||
[Benchmark]
|
||||
public void SelectMobilesNew()
|
||||
{
|
||||
SelectMobiles<Mobile>(sector, bounds);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void SelectMobilesLinq()
|
||||
{
|
||||
SelectMobilesLinq<Mobile>(sector, bounds);
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectMobilesLinq<T>(Sector s, Server.Rectangle2D bounds) where T : Mobile
|
||||
{
|
||||
return s.Mobiles.OfType<T>().Where(o => o != null && !o.Deleted && bounds.Contains(o.Location));
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectMobiles<T>(Sector s, Server.Rectangle2D bounds) where T : Mobile
|
||||
{
|
||||
List<T> entities = new List<T>(s.Mobiles.Count);
|
||||
Type type = typeof(T);
|
||||
for (int i = s.Mobiles.Count - 1; i >= 0; --i)
|
||||
{
|
||||
Mobile mob = s.Mobiles[i];
|
||||
if (mob != null && !mob.Deleted && bounds.Contains(mob.Location) && type.IsAssignableFrom(mob.GetType()))
|
||||
entities.Add(mob as T);
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Entities
|
||||
[Benchmark]
|
||||
public void SelectEntitiesNew()
|
||||
{
|
||||
SelectEntities(sector, bounds);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void SelectEntitiesLinq()
|
||||
{
|
||||
SelectEntitiesLinq(sector, bounds);
|
||||
}
|
||||
|
||||
public IEnumerable<Server.IEntity> SelectEntitiesLinq(Sector s, Server.Rectangle2D bounds)
|
||||
{
|
||||
return Enumerable.Empty<IEntity>()
|
||||
.Union(s.Mobiles.Where(o => o != null && !o.Deleted))
|
||||
.Union(s.BItems.Where(o => o != null && !o.Deleted && o.Parent == null))
|
||||
.Where(o => bounds.Contains(o.Location));
|
||||
}
|
||||
|
||||
private readonly List<Server.IEntity> entities = new (10);
|
||||
public IEnumerable<Server.IEntity> SelectEntities(Sector s, Server.Rectangle2D bounds)
|
||||
{
|
||||
entities.Clear();
|
||||
entities.Capacity = s.Mobiles.Count + s.BItems.Count;
|
||||
for (int i = s.Mobiles.Count - 1, j = s.BItems.Count - 1; i >= 0 || j >= 0; --i, --j)
|
||||
{
|
||||
if (j >= 0)
|
||||
{
|
||||
BItem BItem = s.BItems[j];
|
||||
if (BItem != null && !BItem.Deleted && BItem.Parent == null && bounds.Contains(BItem.Location))
|
||||
entities.Add(BItem);
|
||||
}
|
||||
if (i >= 0)
|
||||
{
|
||||
Mobile mob = s.Mobiles[i];
|
||||
if (mob != null && !mob.Deleted && bounds.Contains(mob.Location))
|
||||
entities.Add(mob);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
public class BItem : Server.IPoint3D, IEntity
|
||||
{
|
||||
public object Parent { get; set; } = null;
|
||||
|
||||
public bool Deleted { get; set; } = false;
|
||||
|
||||
public int Z { get; set; } = 1;
|
||||
|
||||
public int X { get; set; } = 1;
|
||||
|
||||
public int Y { get; set; } = 1;
|
||||
|
||||
public Serial Serial => throw new System.NotImplementedException();
|
||||
|
||||
public Point3D Location { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
|
||||
public Map Map { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
|
||||
|
||||
public Region Region => throw new System.NotImplementedException();
|
||||
|
||||
public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
|
||||
public int Hue { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
|
||||
public Direction Direction { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
|
||||
public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public int TypeRef => throw new NotImplementedException();
|
||||
|
||||
Point3D IEntity.Location => throw new NotImplementedException();
|
||||
|
||||
Map IEntity.Map => throw new NotImplementedException();
|
||||
|
||||
int IPoint3D.Z => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.X => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.Y => throw new NotImplementedException();
|
||||
|
||||
DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
int ISerializable.TypeRef => throw new NotImplementedException();
|
||||
|
||||
Serial ISerializable.Serial => throw new NotImplementedException();
|
||||
|
||||
bool ISerializable.Deleted => throw new NotImplementedException();
|
||||
|
||||
public BItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void ProcessDelta()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnStatsQuery(Server.Mobile m)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void InvalidateProperties()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(IEntity other)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveBItem(BItem BItem)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IEntity.MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IEntity.ProcessDelta()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool IEntity.InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool IEntity.InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveItem(Item item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class Mobile : Server.IPoint3D, IEntity
|
||||
{
|
||||
public bool Deleted { get; set; } = false;
|
||||
|
||||
public int Z { get; set; } = 1;
|
||||
|
||||
public int X { get; set; } = 1;
|
||||
|
||||
public int Y { get; set; } = 1;
|
||||
|
||||
public Serial Serial => throw new System.NotImplementedException();
|
||||
|
||||
public Point3D Location { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
|
||||
public Map Map { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
|
||||
|
||||
public Region Region => throw new System.NotImplementedException();
|
||||
|
||||
public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
|
||||
public int Hue { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
|
||||
public Direction Direction { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
|
||||
public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public int TypeRef => throw new NotImplementedException();
|
||||
|
||||
Point3D IEntity.Location => throw new NotImplementedException();
|
||||
|
||||
Map IEntity.Map => throw new NotImplementedException();
|
||||
|
||||
int IPoint3D.Z => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.X => throw new NotImplementedException();
|
||||
|
||||
int IPoint2D.Y => throw new NotImplementedException();
|
||||
|
||||
DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
int ISerializable.TypeRef => throw new NotImplementedException();
|
||||
|
||||
Serial ISerializable.Serial => throw new NotImplementedException();
|
||||
|
||||
bool ISerializable.Deleted => throw new NotImplementedException();
|
||||
|
||||
public Mobile()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void ProcessDelta()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnStatsQuery(Server.Mobile m)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void InvalidateProperties()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public int CompareTo(IEntity other)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveBItem(BItem BItem)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IEntity.MoveToWorld(Point3D location, Map map)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IEntity.ProcessDelta()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool IEntity.InRange(Point2D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool IEntity.InRange(Point3D p, int range)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.BeforeSerialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Deserialize(IGenericReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Serialize(IGenericWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ISerializable.SetTypeRef(Type type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveItem(Item item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class BaseMulti : BItem
|
||||
{
|
||||
public MultiComponentList Components = MultiComponentList.Empty;
|
||||
|
||||
public BaseMulti()
|
||||
{
|
||||
for (int i = 0; i < 20; ++i)
|
||||
for (int j = 0; j < 20; ++j)
|
||||
for (int z = 0; z < 20; ++z)
|
||||
Components.Add(123, i, j, z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Sector
|
||||
{
|
||||
public List<BItem> BItems { get; set; } = new List<BItem>();
|
||||
public List<Mobile> Mobiles { get; set; } = new List<Mobile>();
|
||||
public List<BaseMulti> Multis { get; set; } = new List<BaseMulti>();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
using BenchmarkDotNet.Running;
|
||||
using Benchmarks.Benchmarks.Rng;
|
||||
using Benchmarks.EntitiesSelectors;
|
||||
using Benchmarks.ItemSelectors;
|
||||
using Benchmarks.MobileSelectors;
|
||||
using Benchmarks.MultiSelectors;
|
||||
using Benchmarks.MultiTilesSelectors;
|
||||
|
||||
namespace Benchmarks
|
||||
{
|
||||
|
|
@ -15,10 +19,14 @@ namespace Benchmarks
|
|||
// var textEncoding = BenchmarkRunner.Run<BenchmarkTextEncoding>();
|
||||
// var logging = BenchmarkRunner.Run<BenchmarkConsoleLogging>();
|
||||
// var gumpPacket = BenchmarkRunner.Run<OutgoingGumpPacketBenchmarks>();
|
||||
// MapSelectors.Init();
|
||||
// var mapSelectors = BenchmarkRunner.Run<MapSelectors>();
|
||||
// var rngTest = BenchmarkRunner.Run<BenchmarkXoshiro>();
|
||||
var doubleRngText = BenchmarkRunner.Run<BenchmarkDoubleVsFixed>();
|
||||
//var doubleRngText = BenchmarkRunner.Run<BenchmarkDoubleVsFixed>();
|
||||
|
||||
//var mapEntitiesSelectors = BenchmarkRunner.Run<MapEntitiesSelectors>();
|
||||
//var mapMobilesSelectors = BenchmarkRunner.Run<MapMobileSelectors>();
|
||||
//var mapMultiTilesSelectors = BenchmarkRunner.Run<MapMultiTilesSelectors>();
|
||||
//var mapMultiSelectors = BenchmarkRunner.Run<MapMultiSelectors>();
|
||||
var mapItemsSelectors = BenchmarkRunner.Run<MapItemSelectors>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue