Skip to content

Instantly share code, notes, and snippets.

@aalmada
Last active February 9, 2024 10:56
Show Gist options
  • Save aalmada/88b58981a42da75b9b0c75efb2df7e6a to your computer and use it in GitHub Desktop.
Save aalmada/88b58981a42da75b9b0c75efb2df7e6a to your computer and use it in GitHub Desktop.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Order;
using BenchmarkDotNet.Reports;
using NetFabric.Numerics;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
[Config(typeof(Config))]
[MemoryDiagnoser]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
[HideColumns(Column.EnvironmentVariables, Column.RatioSD, Column.Error)]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
[CategoriesColumn]
public class PopulateArraysBenchmarks
{
int[]? concatArray;
int[]? copyToArray;
List<int>? list;
[Params(10_000)]
public int ArraySize { get; set; }
[GlobalSetup]
public void GlobalSetup()
{
var source = Enumerable.Range(0, ArraySize);
concatArray = source.ToArray();
copyToArray = source.ToArray();
list = source.ToList();
}
[Benchmark(Baseline = true)]
[BenchmarkCategory("Manual")]
public int[] ArrayIndexInitializer()
=> AddValuesToArrayMethods.ArrayIndexInitializer(ArraySize);
[Benchmark]
[BenchmarkCategory("Manual")]
public int[] ArrayIndexInitializer2()
=> AddValuesToArrayMethods.ArrayIndexInitializer2(ArraySize);
[Benchmark]
[BenchmarkCategory("Manual")]
public int[] SetValueMethod()
=> AddValuesToArrayMethods.SetValueMethod(ArraySize);
[Benchmark(Baseline = true)]
[BenchmarkCategory("Populated Collection")]
public int[] ListCollection()
=> AddValuesToArrayMethods.UsingList(list!);
[Benchmark]
[BenchmarkCategory("Populated Collection")]
public int[] LinqConcat()
=> AddValuesToArrayMethods.LinqConcat(concatArray!);
[Benchmark]
[BenchmarkCategory("Populated Collection")]
public int[] ArrayCopyToMethod()
=> AddValuesToArrayMethods.ArrayCopyToMethod(ArraySize, copyToArray!);
[Benchmark(Baseline = true)]
[BenchmarkCategory("Collection Projection")]
public int[] ArraySelectToArray()
=> copyToArray!.Select(item => item * 2).ToArray();
[Benchmark]
[BenchmarkCategory("Collection Projection")]
public int[] ListSelectToArray()
=> list!.Select(item => item * 2).ToArray();
[Benchmark]
[BenchmarkCategory("Collection Projection")]
public int[] SpanTensor()
=> AddValuesToArrayMethods.SpanTensor(copyToArray!);
[Benchmark]
[BenchmarkCategory("Collection Projection")]
public int[] ListAsSpanTensor()
=> AddValuesToArrayMethods.ListAsSpanTensor(list!);
}
public static class AddValuesToArrayMethods
{
public static int[] ArrayIndexInitializer(int arraySize)
{
var array = new int[arraySize];
for (var index = 0; index < arraySize; index++)
array[index] = index;
return array;
}
public static int[] ArrayIndexInitializer2(int arraySize)
{
var array = new int[arraySize];
for (var index = 0; index < array.Length; index++)
array[index] = index;
return array;
}
public static int[] SetValueMethod(int arraySize)
{
var array = new int[arraySize];
for (var index = 0; index < arraySize; index++)
array.SetValue(value: index, index: index);
return array;
}
public static int[] ArrayCopyToMethod(int arraySize, int[] array)
{
var array1 = new int[arraySize];
array.CopyTo(array1, 0);
return array1;
}
public static int[] UsingList(List<int> list)
=> list.ToArray();
public static int[] LinqConcat(int[] array)
=> Array.Empty<int>().Concat(array).ToArray();
public static int[] SpanTensor(ReadOnlySpan<int> source)
{
var array = new int[source.Length];
Tensor.Multiply(source, 2, array);
return array;
}
public static int[] ListAsSpanTensor(List<int> list)
=> SpanTensor(CollectionsMarshal.AsSpan(list));
}
class Config : ManualConfig
{
public Config()
=> WithSummaryStyle(SummaryStyle.Default.WithRatioStyle(RatioStyle.Trend));
}

BenchmarkDotNet v0.13.12, macOS Sonoma 14.3 (23D56) [Darwin 23.3.0]
Apple M1, 1 CPU, 8 logical and 8 physical cores
.NET SDK 8.0.100
  [Host]     : .NET 8.0.0 (8.0.23.53103), Arm64 RyuJIT AdvSIMD
  DefaultJob : .NET 8.0.0 (8.0.23.53103), Arm64 RyuJIT AdvSIMD

EnvironmentVariables=Empty  

Method Categories ArraySize Mean StdDev Ratio Gen0 Allocated Alloc Ratio
SpanTensor Collection Projection 10000 1.602 μs 0.0052 μs 4.07x faster 6.3286 39.09 KB 1.00x less
ListAsSpanTensor Collection Projection 10000 1.625 μs 0.0104 μs 4.01x faster 6.3286 39.09 KB 1.00x less
ArraySelectToArray Collection Projection 10000 6.523 μs 0.0147 μs baseline 6.3629 39.13 KB
ListSelectToArray Collection Projection 10000 6.535 μs 0.0135 μs 1.00x slower 6.3629 39.16 KB 1.00x more
ArrayIndexInitializer Manual 10000 4.027 μs 0.0133 μs baseline 6.3248 39.09 KB
ArrayIndexInitializer2 Manual 10000 4.055 μs 0.0088 μs 1.01x slower 6.3248 39.09 KB 1.00x more
SetValueMethod Manual 10000 63.367 μs 0.3865 μs 15.74x slower 44.5557 273.46 KB 7.00x more
ArrayCopyToMethod Populated Collection 10000 1.469 μs 0.0161 μs 1.04x faster 6.3286 39.09 KB 1.00x more
ListCollection Populated Collection 10000 1.532 μs 0.0124 μs baseline 6.3286 39.09 KB
LinqConcat Populated Collection 10000 1.547 μs 0.0063 μs 1.01x slower 6.3686 39.2 KB 1.00x more
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment