Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save udlose/157594d3aa585ccd780d270f9e750883 to your computer and use it in GitHub Desktop.

Select an option

Save udlose/157594d3aa585ccd780d270f9e750883 to your computer and use it in GitHub Desktop.
.NET Benchmark for comparing iteration using foreach over ArrayList vs List<T> containing Reference Type
[MemoryDiagnoser]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
[CategoriesColumn]
[Config(typeof(IterationBenchmarks.IterationBenchmarksConfig))]
public class IterationBenchmarks
{
[Params(1_000, 10_000, 50_000)]
public int Count;
private ArrayList _arrayList = null;
private List<Person> _listOfPerson = null;
private Consumer _consumer = null;
[GlobalSetup]
public void GlobalSetup()
{
_arrayList = new ArrayList(Count);
_listOfPerson = new List<Person>(Count);
for (int i = 0; i < Count; i++)
{
Person p = new Person(i, "Dwight Schrute");
_arrayList.Add(p); // boxed
_listOfPerson.Add(p);
}
_consumer = new Consumer();
}
[Benchmark(Baseline = true, Description = "ArrayList<Person> foreach")]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ArrayList_Foreach()
{
foreach (object item in _arrayList)
{
IPerson value = (Person)item; // unbox
_consumer.Consume(value);
}
}
[Benchmark(Description = "List<Person> foreach")]
[MethodImpl(MethodImplOptions.NoInlining)]
public void List_Foreach()
{
foreach (IPerson p in _listOfPerson)
{
_consumer.Consume(p);
}
}
private class IterationBenchmarksConfig : ManualConfig
{
public IterationBenchmarksConfig()
{
SummaryStyle = BenchmarkDotNet.Reports.SummaryStyle.Default.WithRatioStyle(RatioStyle.Trend);
}
}
}
public static class Program
{
public static void Main(string[] args)
{
BenchmarkRunner.Run<IterationBenchmarks>();
}
}
public interface IPerson
{
int Compute();
}
public class Person : IPerson
{
public readonly int Id;
public readonly string Name;
public Person(int id, string name)
{
Id = id;
Name = name;
}
public int Compute()
{
// Cheap deterministic work; no allocations; good for net48 + net8.
Random rand = new Random();
int x = rand.Next() ^ (Id * 397);
x = (x << 5) | (int)((uint)x >> 27);
x = x * 31 + Id;
return x;
}
}
// Run time: 00:04:25 (265.3 sec), executed benchmarks: 6
// * Summary *
//
// BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.7628/25H2/2025Update/HudsonValley2)
// AMD Ryzen 9 7945HX with Radeon Graphics 2.50GHz, 1 CPU, 32 logical and 16 physical cores
//
// .NET SDK 10.0.102
// [Host] : .NET 10.0.2 (10.0.2, 10.0.225.61305), X86 RyuJIT x86-64-v4
//
//| Method | Count | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio |
//|---------------------------- |------ |-----------:|----------:|----------:|-------------:|--------:|----------:|------------:|
//| 'ArrayList<Person> foreach' | 1000 | 5.489 μs | 0.1093 μs | 0.2682 μs | baseline | | 28 B | |
//| 'List<Person> foreach' | 1000 | 1.414 μs | 0.0282 μs | 0.0664 μs | 3.89x faster | 0.26x | - | NA |
//| | | | | | | | | |
//| 'ArrayList<Person> foreach' | 10000 | 52.598 μs | 1.0151 μs | 0.8998 μs | baseline | | 28 B | |
//| 'List<Person> foreach' | 10000 | 13.761 μs | 0.2710 μs | 0.6336 μs | 3.83x faster | 0.18x | - | NA |
//| | | | | | | | | |
//| 'ArrayList<Person> foreach' | 50000 | 262.266 μs | 5.0160 μs | 5.9711 μs | baseline | | 30 B | |
//| 'List<Person> foreach' | 50000 | 69.129 μs | 1.3808 μs | 2.1086 μs | 3.80x faster | 0.14x | - | NA |
// Run time: 00:04:54 (294.4 sec), executed benchmarks: 6
// * Summary *
//
// BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.7628/25H2/2025Update/HudsonValley2)
// AMD Ryzen 9 7945HX with Radeon Graphics 2.50GHz, 1 CPU, 32 logical and 16 physical cores
//
// [Host] : .NET Framework 4.8.1 (4.8.9221.0), X86 LegacyJIT
// DefaultJob : .NET Framework 4.8.1 (4.8.9221.0), X86 LegacyJIT
//
//| Method | Count | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
//|---------------------------- |------ |-----------:|----------:|-----------:|-------------:|--------:|-------:|----------:|------------:|
//| 'ArrayList<Person> foreach' | 1000 | 6.434 μs | 0.1274 μs | 0.2875 μs | baseline | | 0.0153 | 28 B | |
//| 'List<Person> foreach' | 1000 | 3.182 μs | 0.0627 μs | 0.1162 μs | 2.02x faster | 0.12x | - | - | NA |
//| | | | | | | | | | |
//| 'ArrayList<Person> foreach' | 10000 | 66.098 μs | 1.3836 μs | 3.9699 μs | baseline | | - | 28 B | |
//| 'List<Person> foreach' | 10000 | 31.653 μs | 0.6145 μs | 1.3227 μs | 2.09x faster | 0.15x | - | - | NA |
//| | | | | | | | | | |
//| 'ArrayList<Person> foreach' | 50000 | 317.880 μs | 6.3573 μs | 14.3494 μs | baseline | | - | 28 B | |
//| 'List<Person> foreach' | 50000 | 151.201 μs | 3.0140 μs | 5.8787 μs | 2.11x faster | 0.12x | - | - | NA |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment