forked from mirror/DotRecast
157 lines
4.1 KiB
C#
157 lines
4.1 KiB
C#
using System;
|
|
using System.Buffers;
|
|
using System.Collections.Generic;
|
|
using System.Net.Sockets;
|
|
using DotRecast.Core.Buffers;
|
|
using DotRecast.Core.Collections;
|
|
using NUnit.Framework;
|
|
|
|
namespace DotRecast.Core.Test;
|
|
|
|
public class RcArrayBenchmarkTests
|
|
{
|
|
private const int StepLength = 512;
|
|
private const int RandomLoop = 1000;
|
|
private readonly RcRand _rand = new RcRand();
|
|
|
|
private (string title, long ticks) Bench(string title, Action<int> source)
|
|
{
|
|
var begin = RcFrequency.Ticks;
|
|
for (int step = StepLength; step > 0; --step)
|
|
{
|
|
for (int i = 0; i < RandomLoop; ++i)
|
|
{
|
|
source.Invoke(step);
|
|
}
|
|
}
|
|
|
|
var end = RcFrequency.Ticks - begin;
|
|
return (title, end);
|
|
}
|
|
|
|
|
|
private void RoundForArray(int len)
|
|
{
|
|
var array = new int[len];
|
|
for (int ii = 0; ii < len; ++ii)
|
|
{
|
|
array[ii] = _rand.NextInt32();
|
|
}
|
|
}
|
|
|
|
|
|
private void RoundForPureRentArray(int len)
|
|
{
|
|
var array = ArrayPool<int>.Shared.Rent(len);
|
|
for (int ii = 0; ii < array.Length; ++ii)
|
|
{
|
|
array[ii] = _rand.NextInt32();
|
|
}
|
|
|
|
ArrayPool<int>.Shared.Return(array);
|
|
}
|
|
|
|
|
|
private void RoundForRcRentedArray(int len)
|
|
{
|
|
using var rentedArray = RcRentedArray.Rent<int>(len);
|
|
var array = rentedArray.AsArray();
|
|
for (int i = 0; i < rentedArray.Length; ++i)
|
|
{
|
|
array[i] = _rand.NextInt32();
|
|
}
|
|
}
|
|
|
|
|
|
private void RoundForRcStackArray(int len)
|
|
{
|
|
var array = new RcStackArray512<int>();
|
|
for (int ii = 0; ii < len; ++ii)
|
|
{
|
|
array[ii] = _rand.NextInt32();
|
|
}
|
|
}
|
|
|
|
private void RoundForStackalloc(int len)
|
|
{
|
|
Span<int> array = stackalloc int[len];
|
|
for (int ii = 0; ii < len; ++ii)
|
|
{
|
|
array[ii] = _rand.NextInt32();
|
|
}
|
|
}
|
|
|
|
|
|
[Test]
|
|
public void TestBenchmarkArrays()
|
|
{
|
|
var results = new List<(string title, long ticks)>();
|
|
results.Add(Bench("new int[len]", RoundForArray));
|
|
results.Add(Bench("ArrayPool<int>.Shared.Rent(len)", RoundForPureRentArray));
|
|
results.Add(Bench("RcRentedArray.Rent<int>(len)", RoundForRcRentedArray));
|
|
results.Add(Bench("new RcStackArray512<int>()", RoundForRcStackArray));
|
|
results.Add(Bench("stackalloc int[len]", RoundForStackalloc));
|
|
|
|
results.Sort((x, y) => x.ticks.CompareTo(y.ticks));
|
|
|
|
foreach (var t in results)
|
|
{
|
|
Console.WriteLine($"{t.title} {t.ticks / (double)TimeSpan.TicksPerMillisecond} ms");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestSpanVsArray()
|
|
{
|
|
var r = new RcRand();
|
|
var list = new List<(long[] src, long[] dest)>();
|
|
for (int i = 0; i < 14; ++i)
|
|
{
|
|
var s = new long[(int)Math.Pow(2, i + 1)];
|
|
var d = new long[(int)Math.Pow(2, i + 1)];
|
|
for (int ii = 0; ii < s.Length; ++ii)
|
|
{
|
|
s[ii] = r.NextInt32();
|
|
}
|
|
|
|
list.Add((s, d));
|
|
}
|
|
|
|
var results = new List<(string title, long ticks)>();
|
|
for (int i = 0; i < list.Count; ++i)
|
|
{
|
|
var seq = i;
|
|
|
|
Array.Fill(list[seq].dest, 0);
|
|
var resultLong = Bench($"long[{list[seq].src.Length}]", _ =>
|
|
{
|
|
var v = list[seq];
|
|
RcArrays.Copy(v.src, 0, v.dest, 0, v.src.Length);
|
|
});
|
|
|
|
|
|
Array.Fill(list[seq].dest, 0);
|
|
var resultSpan = Bench($"Span<long[], {list[seq].src.Length}>", _ =>
|
|
{
|
|
var v = list[seq];
|
|
RcSpans.Copy<long>(v.src, 0, v.dest, 0, v.src.Length);
|
|
});
|
|
|
|
|
|
results.Add(resultLong);
|
|
results.Add(resultSpan);
|
|
}
|
|
|
|
|
|
int newLine = 0;
|
|
foreach (var t in results)
|
|
{
|
|
Console.WriteLine($"{t.title}: {t.ticks / (double)TimeSpan.TicksPerMillisecond} ms");
|
|
newLine += 1;
|
|
if (0 == (newLine % 2))
|
|
{
|
|
Console.WriteLine("");
|
|
}
|
|
}
|
|
}
|
|
} |