Skip to content

Instantly share code, notes, and snippets.

@benaadams
Forked from Thealexbarney/IListPerformance.cs
Last active December 5, 2018 22:12
Show Gist options
  • Save benaadams/ba3c008a328f02c75663213cd9affa65 to your computer and use it in GitHub Desktop.
Save benaadams/ba3c008a328f02c75663213cd9affa65 to your computer and use it in GitHub Desktop.
Simple IList performance benchmark
using System;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace IListPerformance
{
public class Program
{
public static void Main(string[] args)
{
int iterations = 50000000;
int[] array = new int[iterations];
List<int> list = new List<int>(array);
ArrayWrapperNonInlined wrapper2 = new ArrayWrapperNonInlined(array);
ArrayWrapper wrapper = new ArrayWrapper(array);
Console.WriteLine("Warming up...");
for (int i = 0; i < 4; i++)
{
SumArray(array);
SumIList(array);
SumArrayWrapper(wrapper);
SumArrayWrapper2(wrapper2);
SumList(list);
SumIList(list);
SumIList(wrapper);
SumGeneric(array);
SumGeneric(list);
SumGeneric(wrapper);
}
Console.WriteLine("Times are in milliseconds\n");
RunTest(x => SumArray(x), array, "Array");
RunTest(x => SumIList(x), array, "Array as IList");
RunTest(x => SumArrayWrapper(x), wrapper, "ArrayWrapper");
RunTest(x => SumArrayWrapper2(x), wrapper2, "ArrayWrapper Non-inlined");
RunTest(x => SumList(x), list, "List");
RunTest(x => SumIList(x), list, "List as IList");
RunTest(x => SumIList(x), wrapper, "ArrayWrapper as IList");
RunTest(x => SumGeneric(x), array, "Array as Generic");
RunTest(x => SumGeneric(x), list, "List as Generic");
RunTest(x => SumGeneric(x), wrapper, "ArrayWrapper as Generic");
}
private static void RunTest<T>(Func<T, int> test, T array, string testName)
{
Stopwatch watch = Stopwatch.StartNew();
var val = test(array);
watch.Stop();
Console.WriteLine($"{watch.ElapsedMilliseconds} \t {testName}");
}
private static int SumArray(int[] array)
{
int result = 0;
for (int i = 0; i < array.Length; i++)
result += array[i];
return result;
}
private static int SumIList(IList<int> ilist)
{
int result = 0;
var count = ilist.Count;
for (int i = 0; i < count; i++)
result += ilist[i];
return result;
}
private static int SumList(List<int> list)
{
int result = 0;
var count = list.Count;
for (int i = 0; i < count; i++)
result += list[i];
return result;
}
private static int SumArrayWrapper(ArrayWrapper wrapper)
{
int result = 0;
var count = wrapper.Count;
for (int i = 0; i < count; i++)
result += wrapper[i];
return result;
}
private static int SumArrayWrapper2(ArrayWrapperNonInlined wrapper)
{
int result = 0;
var count = wrapper.Count;
for (int i = 0; i < count; i++)
result += wrapper[i];
return result;
}
private static int SumGeneric<TList>(TList wrapper)
where TList : IList<int>
{
int result = 0;
var count = wrapper.Count;
for (int i = 0; i < count; i++)
result += wrapper[i];
return result;
}
private struct ArrayWrapperNonInlined : IList<int>
{
private readonly int[] _array;
public int Count
{
[MethodImpl(MethodImplOptions.NoInlining)]
get { return _array.Length; }
}
public ArrayWrapperNonInlined(int[] array)
{
_array = array;
}
public int this[int index]
{
[MethodImpl(MethodImplOptions.NoInlining)]
get { return _array[index]; }
set { _array[index] = value; }
}
public IEnumerator<int> GetEnumerator() { throw new NotImplementedException(); }
IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
public void Add(int item) { throw new NotImplementedException(); }
public void Clear() { throw new NotImplementedException(); }
public bool Contains(int item) { throw new NotImplementedException(); }
public void CopyTo(int[] array, int arrayIndex) { throw new NotImplementedException(); }
public bool Remove(int item) { throw new NotImplementedException(); }
public bool IsReadOnly => true;
public int IndexOf(int item) { throw new NotImplementedException(); }
public void Insert(int index, int item) { throw new NotImplementedException(); }
public void RemoveAt(int index) { throw new NotImplementedException(); }
}
private struct ArrayWrapper : IList<int>
{
private readonly int[] _array;
public int Count => _array.Length;
public ArrayWrapper(int[] array)
{
_array = array;
}
public int this[int index]
{
get { return _array[index]; }
set { _array[index] = value; }
}
public IEnumerator<int> GetEnumerator() { throw new NotImplementedException(); }
IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
public void Add(int item) { throw new NotImplementedException(); }
public void Clear() { throw new NotImplementedException(); }
public bool Contains(int item) { throw new NotImplementedException(); }
public void CopyTo(int[] array, int arrayIndex) { throw new NotImplementedException(); }
public bool Remove(int item) { throw new NotImplementedException(); }
public bool IsReadOnly => true;
public int IndexOf(int item) { throw new NotImplementedException(); }
public void Insert(int index, int item) { throw new NotImplementedException(); }
public void RemoveAt(int index) { throw new NotImplementedException(); }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment