Skip to content

Instantly share code, notes, and snippets.

@bradwilson
Last active January 10, 2024 07:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradwilson/f429e36a9bb4641aa135b9daf7cbb1e9 to your computer and use it in GitHub Desktop.
Save bradwilson/f429e36a9bb4641aa135b9daf7cbb1e9 to your computer and use it in GitHub Desktop.
Benchmarking OfType() vs. custom WhereNotNull() to discard null values
using System;
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Running;
public static class EnumerableExtensions
{
static readonly Func<object, bool> notNullTest = x => x is not null;
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> source)
where T : class =>
source.Where((Func<T?, bool>)notNullTest)!;
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> source)
where T : struct =>
source.Where(x => x.HasValue).Select(x => x!.Value);
}
public class BenchmarkClass
{
const int dataLength = 100_000;
int?[] intData = new int?[dataLength];
string?[] stringData = new string?[dataLength];
public BenchmarkClass()
{
var random = new Random();
for (int idx = 0; idx < dataLength; ++idx)
{
var value = random.Next(100);
if (value != 0)
{
intData[idx] = value;
stringData[idx] = value.ToString();
}
}
}
[Benchmark]
public void Integer_OfType() => intData.OfType<int>().Consume(new Consumer());
[Benchmark]
public void Integer_WhereNotNull() => intData.WhereNotNull().Consume(new Consumer());
[Benchmark]
public void String_OfType() => stringData.OfType<string>().Consume(new Consumer());
[Benchmark]
public void String_WhereNotNull() => stringData.WhereNotNull().Consume(new Consumer());
}
public static class Program
{
public static void Main() =>
BenchmarkRunner.Run<BenchmarkClass>();
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
</ItemGroup>
</Project>
BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.3007/23H2/2023Update/SunValley3)
AMD Ryzen 9 5900X, 1 CPU, 24 logical and 12 physical cores
.NET SDK 8.0.100
  [Host]     : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
  DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
Method Mean Error StdDev
Integer_OfType 3,809.1 us 13.63 us 12.08 us
Integer_WhereNotNull 141.0 us 1.43 us 1.34 us
String_OfType 808.7 us 10.92 us 10.22 us
String_WhereNotNull 472.3 us 0.75 us 0.59 us
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment