Skip to content

Instantly share code, notes, and snippets.

@VisualMelon
Created July 6, 2019 23:22
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 VisualMelon/1ab841a5b9204517675236e6645c537d to your computer and use it in GitHub Desktop.
Save VisualMelon/1ab841a5b9204517675236e6645c537d to your computer and use it in GitHub Desktop.
# depends on BenchmarkDotNet
using System;
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
namespace SkipLastBenchmark
{
public static class Exts
{
static public IEnumerable<T> SkipLast1<T>(this IEnumerable<T> data, int count)
{
if (data == null || count < 0) yield break;
Queue<T> queue = new Queue<T>(data.Take(count));
foreach (T item in data.Skip(count))
{
queue.Enqueue(item);
yield return queue.Dequeue();
}
}
static public IEnumerable<T> SkipLast2<T>(this IEnumerable<T> data, int count)
{
if (data == null || count < 0)
yield break;
if (count == 0)
{
foreach (T item in data)
yield return item;
}
else
{
T[] queue = data.Take(count).ToArray();
int index = 0;
foreach (T item in data.Skip(count))
{
index %= count;
yield return queue[index];
queue[index] = item;
index++;
}
}
}
static public IEnumerable<T> SkipLast3<T>(this IEnumerable<T> source, int count)
{
if (source == null)
throw new ArgumentNullException("Source Enumeration may not be null", nameof(source));
if (count <= 0)
{
foreach (T item in source)
yield return item;
}
else
{
bool yielding = false;
T[] buffer = new T[count];
int index = 0;
foreach (T item in source)
{
if (index == count)
{
index = 0;
yielding = true;
}
if (yielding)
yield return buffer[index];
buffer[index] = item;
index++;
}
}
}
static public IEnumerable<T> SkipLast4<T>(this IEnumerable<T> source, int count)
{
if (source == null)
throw new ArgumentNullException("Source Enumeration may not be null", nameof(source));
if (count <= 0)
{
foreach (T item in source)
yield return item;
}
else
{
T[] buffer = new T[count];
using (var e = source.GetEnumerator())
{
// initial filling of buffer
for (int i = 0; i < buffer.Length; i++)
{
if (!e.MoveNext())
yield break;
buffer[i] = e.Current;
}
int index = 0;
while (e.MoveNext())
{
yield return buffer[index];
buffer[index] = e.Current;
index = (index + 1) % count;
}
}
}
}
}
class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<Bench>();
}
}
public class Bench
{
public IEnumerable<int> Lengths => new int[] { 0, 100, 100000 };
public IEnumerable<int> Counts => new int[] { 0, 10, 1000 };
[ParamsSource(nameof(Lengths))]
public int Length { get; set; }
[ParamsSource(nameof(Counts))]
public int Count { get; set; }
public IEnumerable<int> Array { get; set; }
public IEnumerable<int> Range { get; set; }
public IEnumerable<int> Thing { get; set; }
[GlobalSetup]
public void GlobalSetup()
{
Array = new int[Length];
Range = Enumerable.Range(0, Length);
Thing = MysteryRange(Length);
}
static IEnumerable<int> MysteryRange(int count)
{
for (int i = 0; i < count; i++)
yield return i;
}
[GlobalCleanup]
public void GlobalCleanup()
{
// nix
}
[Benchmark]
public void SkipLastNetCoreArrays() { foreach (var a in Array.SkipLast(Count)); }
[Benchmark]
public void SkipLast1Arrays() { foreach (var a in Array.SkipLast1(Count)); }
[Benchmark]
public void SkipLast2Arrays() { foreach (var a in Array.SkipLast2(Count)); }
[Benchmark]
public void SkipLast3Arrays() { foreach (var a in Array.SkipLast3(Count)); }
[Benchmark]
public void SkipLast4Arrays() { foreach (var a in Array.SkipLast4(Count)); }
[Benchmark]
public void SkipLast1Ranges() { foreach (var a in Range.SkipLast1(Count)); }
[Benchmark]
public void SkipLast2Ranges() { foreach (var a in Range.SkipLast2(Count)); }
[Benchmark]
public void SkipLast3Ranges() { foreach (var a in Range.SkipLast3(Count)); }
[Benchmark]
public void SkipLast4Ranges() { foreach (var a in Range.SkipLast4(Count)); }
[Benchmark]
public void SkipLastNetCoreThings() { foreach (var a in Thing.SkipLast(Count)); }
[Benchmark]
public void SkipLast1Things() { foreach (var a in Thing.SkipLast1(Count)); }
[Benchmark]
public void SkipLast2Things() { foreach (var a in Thing.SkipLast2(Count)); }
[Benchmark]
public void SkipLast3Things() { foreach (var a in Thing.SkipLast3(Count)); }
[Benchmark]
public void SkipLast4Things() { foreach (var a in Thing.SkipLast4(Count)); }
}
}
@VisualMelon
Copy link
Author

SkipLastBenchmark.Bench-20190706-113102


BenchmarkDotNet=v0.11.5, OS=Windows 7 SP1 (6.1.7601.0)
Intel Core i7-2670QM CPU 2.20GHz (Sandy Bridge), 1 CPU, 8 logical and 4 physical cores
Frequency=2143593 Hz, Resolution=466.5065 ns, Timer=TSC
.NET Core SDK=3.0.100-preview6-012264
  [Host]     : .NET Core 3.0.0-preview6-27804-01 (CoreCLR 4.700.19.30373, CoreFX 4.700.19.30308), 64bit RyuJIT
  DefaultJob : .NET Core 3.0.0-preview6-27804-01 (CoreCLR 4.700.19.30373, CoreFX 4.700.19.30308), 64bit RyuJIT

Legends

  • Length : Value of the 'Length' parameter
  • Count : Value of the 'Count' parameter
  • Mean : Arithmetic mean of all measurements
  • Error : Half of 99.9% confidence interval
  • StdDev : Standard deviation of all measurements
  • Median : Value separating the higher half of all measurements (50th percentile)
MethodLengthCount Mean Error StdDev Median
SkipLastNetCoreArrays0094.52 ns0.8521 ns0.7554 ns94.65 ns
SkipLast1Arrays00192.17 ns2.8857 ns2.4097 ns191.47 ns
SkipLast2Arrays0061.30 ns0.9265 ns0.8213 ns61.22 ns
SkipLast3Arrays0059.16 ns0.3548 ns0.3319 ns59.11 ns
SkipLast4Arrays0060.74 ns0.2400 ns0.2245 ns60.81 ns
SkipLast1Ranges00110.22 ns1.9719 ns1.8445 ns110.02 ns
SkipLast2Ranges0058.71 ns1.1016 ns0.8601 ns58.37 ns
SkipLast3Ranges0056.39 ns0.1652 ns0.1465 ns56.38 ns
SkipLast4Ranges0056.32 ns0.6962 ns0.5814 ns56.17 ns
SkipLastNetCoreThings0098.44 ns0.6445 ns0.6029 ns98.31 ns
SkipLast1Things00190.33 ns0.9272 ns0.7743 ns190.28 ns
SkipLast2Things0077.45 ns0.3684 ns0.3446 ns77.42 ns
SkipLast3Things0077.03 ns0.3176 ns0.2971 ns77.00 ns
SkipLast4Things0077.51 ns0.4102 ns0.3837 ns77.48 ns
SkipLastNetCoreArrays01077.06 ns0.8803 ns0.8235 ns76.72 ns
SkipLast1Arrays010260.03 ns0.7995 ns0.7479 ns260.21 ns
SkipLast2Arrays010237.88 ns2.7745 ns2.5952 ns237.28 ns
SkipLast3Arrays01076.85 ns1.5353 ns1.7065 ns76.19 ns
SkipLast4Arrays01077.31 ns0.5970 ns0.5584 ns77.08 ns
SkipLast1Ranges010111.26 ns0.3006 ns0.2665 ns111.21 ns
SkipLast2Ranges01090.45 ns0.5031 ns0.4201 ns90.56 ns
SkipLast3Ranges01077.92 ns2.2161 ns1.9645 ns77.09 ns
SkipLast4Ranges01077.07 ns1.6838 ns2.3049 ns76.04 ns
SkipLastNetCoreThings01089.39 ns2.1110 ns2.5130 ns88.54 ns
SkipLast1Things010268.89 ns1.0638 ns0.8305 ns269.06 ns
SkipLast2Things010249.74 ns0.9372 ns0.8308 ns249.38 ns
SkipLast3Things01092.70 ns0.2643 ns0.2472 ns92.64 ns
SkipLast4Things010119.01 ns2.4273 ns5.7688 ns118.68 ns
SkipLastNetCoreArrays01000100.32 ns0.3806 ns0.3374 ns100.18 ns
SkipLast1Arrays01000331.89 ns1.2132 ns1.1348 ns331.52 ns
SkipLast2Arrays01000238.13 ns0.4682 ns0.4379 ns238.15 ns
SkipLast3Arrays01000443.05 ns4.5160 ns4.2243 ns443.37 ns
SkipLast4Arrays01000403.55 ns2.5047 ns2.0915 ns403.26 ns
SkipLast1Ranges01000136.56 ns3.5703 ns9.8932 ns140.41 ns
SkipLast2Ranges01000115.09 ns0.3782 ns0.3353 ns115.11 ns
SkipLast3Ranges01000404.82 ns8.1296 ns8.3485 ns407.10 ns
SkipLast4Ranges01000406.45 ns7.8010 ns8.3470 ns406.22 ns
SkipLastNetCoreThings01000119.97 ns1.0089 ns0.9437 ns119.49 ns
SkipLast1Things01000337.43 ns1.6595 ns1.5523 ns336.69 ns
SkipLast2Things01000317.76 ns1.2803 ns1.1976 ns317.47 ns
SkipLast3Things01000432.27 ns8.3622 ns8.2128 ns429.90 ns
SkipLast4Things01000424.42 ns3.3114 ns3.0975 ns424.25 ns
SkipLastNetCoreArrays10001,496.12 ns3.9343 ns3.6801 ns1,496.26 ns
SkipLast1Arrays10003,577.88 ns7.8219 ns7.3167 ns3,577.47 ns
SkipLast2Arrays10001,616.91 ns8.4080 ns6.5644 ns1,615.73 ns
SkipLast3Arrays10002,109.04 ns5.6291 ns5.2655 ns2,106.44 ns
SkipLast4Arrays10002,078.98 ns11.6700 ns10.9162 ns2,078.00 ns
SkipLast1Ranges10003,383.20 ns7.0656 ns6.6091 ns3,383.85 ns
SkipLast2Ranges10002,046.10 ns5.7535 ns5.3818 ns2,045.26 ns
SkipLast3Ranges10002,153.31 ns5.1561 ns4.8230 ns2,151.37 ns
SkipLast4Ranges10002,133.00 ns19.8706 ns17.6147 ns2,128.18 ns
SkipLastNetCoreThings10001,740.53 ns51.5063 ns65.1389 ns1,727.84 ns
SkipLast1Things10003,838.19 ns16.2289 ns15.1806 ns3,836.69 ns
SkipLast2Things10001,744.54 ns6.9930 ns6.5413 ns1,745.29 ns
SkipLast3Things10001,705.52 ns4.6355 ns4.3360 ns1,705.78 ns
SkipLast4Things10001,695.68 ns4.6860 ns4.3833 ns1,694.51 ns
SkipLastNetCoreArrays100102,733.73 ns5.2760 ns4.9352 ns2,733.49 ns
SkipLast1Arrays100103,484.25 ns6.9189 ns6.4720 ns3,484.64 ns
SkipLast2Arrays100102,781.23 ns8.5018 ns7.9526 ns2,783.27 ns
SkipLast3Arrays100102,251.64 ns4.6655 ns4.3641 ns2,251.99 ns
SkipLast4Arrays100102,114.38 ns6.6747 ns6.2435 ns2,115.72 ns
SkipLast1Ranges100103,367.97 ns83.8485 ns243.2597 ns3,467.37 ns
SkipLast2Ranges100102,603.48 ns5.3081 ns4.9652 ns2,602.52 ns
SkipLast3Ranges100102,301.90 ns7.6143 ns6.7499 ns2,302.60 ns
SkipLast4Ranges100102,109.45 ns8.1434 ns7.6174 ns2,108.79 ns
SkipLastNetCoreThings100102,758.94 ns14.5202 ns12.8718 ns2,761.45 ns
SkipLast1Things100103,741.48 ns15.7257 ns14.7098 ns3,743.52 ns
SkipLast2Things100103,268.22 ns69.6281 ns80.1838 ns3,241.15 ns
SkipLast3Things100102,317.00 ns19.0728 ns16.9076 ns2,317.91 ns
SkipLast4Things100102,721.31 ns54.2785 ns117.9970 ns2,745.69 ns
SkipLastNetCoreArrays10010002,175.95 ns14.5384 ns12.8879 ns2,172.64 ns
SkipLast1Arrays10010002,750.66 ns14.8926 ns13.9305 ns2,754.45 ns
SkipLast2Arrays1001000927.77 ns2.2752 ns2.1282 ns927.14 ns
SkipLast3Arrays10010001,577.69 ns3.1901 ns2.8279 ns1,576.82 ns
SkipLast4Arrays10010001,203.56 ns7.5855 ns7.0955 ns1,201.97 ns
SkipLast1Ranges10010001,234.57 ns8.4862 ns7.5228 ns1,233.19 ns
SkipLast2Ranges1001000300.37 ns3.4852 ns3.2601 ns300.53 ns
SkipLast3Ranges10010002,017.32 ns26.7232 ns24.9969 ns2,007.69 ns
SkipLast4Ranges10010001,533.77 ns15.7411 ns14.7243 ns1,529.84 ns
SkipLastNetCoreThings10010002,244.49 ns12.9202 ns12.0855 ns2,244.29 ns
SkipLast1Things10010003,566.32 ns42.8585 ns40.0898 ns3,547.28 ns
SkipLast2Things10010002,709.74 ns4.9709 ns4.4065 ns2,709.41 ns
SkipLast3Things10010001,808.90 ns4.9616 ns4.3983 ns1,809.03 ns
SkipLast4Things10010001,507.32 ns5.7221 ns4.4674 ns1,506.75 ns
SkipLastNetCoreArrays10000001,346,506.72 ns4,920.2559 ns4,602.4105 ns1,347,498.47 ns
SkipLast1Arrays10000003,356,476.68 ns8,380.4380 ns7,429.0400 ns3,355,003.36 ns
SkipLast2Arrays10000001,491,103.31 ns2,673.8534 ns2,501.1241 ns1,491,366.51 ns
SkipLast3Arrays10000001,498,072.45 ns3,167.3327 ns2,962.7250 ns1,498,109.44 ns
SkipLast4Arrays10000001,536,940.43 ns3,669.2302 ns3,432.2002 ns1,538,079.12 ns
SkipLast1Ranges10000003,106,530.98 ns61,504.2603 ns156,547.9799 ns3,145,387.06 ns
SkipLast2Ranges10000001,938,133.62 ns2,214.3457 ns2,071.3004 ns1,938,124.81 ns
SkipLast3Ranges10000001,950,613.10 ns22,745.7191 ns20,163.4875 ns1,940,924.31 ns
SkipLast4Ranges10000001,499,284.67 ns9,054.9129 ns8,469.9712 ns1,495,816.54 ns
SkipLastNetCoreThings10000001,483,145.64 ns11,652.9480 ns10,330.0349 ns1,486,023.55 ns
SkipLast1Things10000003,616,311.49 ns30,812.2704 ns28,821.8169 ns3,612,307.19 ns
SkipLast2Things10000001,650,822.57 ns29,344.2411 ns24,503.7703 ns1,644,940.99 ns
SkipLast3Things10000002,022,209.61 ns2,015.8980 ns1,787.0411 ns2,021,891.42 ns
SkipLast4Things10000002,020,873.22 ns3,097.1151 ns2,897.0434 ns2,020,964.33 ns
SkipLastNetCoreArrays100000103,343,891.81 ns29,999.5397 ns26,593.8106 ns3,329,758.25 ns
SkipLast1Arrays100000104,191,115.98 ns16,150.3103 ns15,107.0102 ns4,192,471.76 ns
SkipLast2Arrays100000102,757,554.50 ns54,654.9204 ns95,723.6842 ns2,715,102.27 ns
SkipLast3Arrays100000102,267,643.96 ns17,906.8654 ns16,750.0930 ns2,271,915.66 ns
SkipLast4Arrays100000102,117,668.33 ns14,020.3580 ns13,114.6516 ns2,121,328.83 ns
SkipLast1Ranges100000102,575,748.16 ns16,771.2296 ns15,687.8186 ns2,577,896.52 ns
SkipLast2Ranges100000102,016,961.93 ns9,553.5107 ns8,468.9384 ns2,016,547.10 ns
SkipLast3Ranges100000102,058,685.76 ns10,114.6655 ns9,461.2644 ns2,060,998.24 ns
SkipLast4Ranges100000102,081,034.33 ns17,464.5716 ns15,481.8878 ns2,077,674.94 ns
SkipLastNetCoreThings100000102,626,660.54 ns14,888.3192 ns13,926.5430 ns2,627,271.49 ns
SkipLast1Things100000103,493,533.79 ns14,802.4900 ns13,846.2583 ns3,491,168.58 ns
SkipLast2Things100000103,782,114.69 ns7,354.0797 ns6,879.0107 ns3,783,145.14 ns
SkipLast3Things100000102,784,520.01 ns3,266.7998 ns3,055.7666 ns2,783,871.88 ns
SkipLast4Things100000102,805,656.20 ns53,084.6968 ns47,058.2010 ns2,786,810.33 ns
SkipLastNetCoreArrays10000010003,219,414.11 ns3,359.1070 ns3,142.1107 ns3,218,225.85 ns
SkipLast1Arrays10000010004,018,749.86 ns7,619.8173 ns7,127.5818 ns4,019,029.76 ns
SkipLast2Arrays10000010003,543,975.41 ns10,935.6161 ns10,229.1821 ns3,541,155.84 ns
SkipLast3Arrays10000010002,891,986.82 ns7,155.7567 ns6,693.4992 ns2,891,807.99 ns
SkipLast4Arrays10000010002,135,899.99 ns10,700.8717 ns10,009.6020 ns2,136,561.36 ns
SkipLast1Ranges10000010002,455,941.77 ns8,165.2179 ns7,637.7499 ns2,455,427.64 ns
SkipLast2Ranges10000010002,114,850.58 ns10,742.1909 ns10,048.2521 ns2,111,093.02 ns
SkipLast3Ranges10000010002,125,203.87 ns11,053.4244 ns10,339.3801 ns2,125,512.81 ns
SkipLast4Ranges10000010002,089,056.42 ns8,764.2002 ns8,198.0383 ns2,085,285.74 ns
SkipLastNetCoreThings10000010002,522,630.93 ns7,186.8495 ns6,722.5834 ns2,523,111.17 ns
SkipLast1Things10000010003,354,383.66 ns14,250.2726 ns13,329.7138 ns3,353,541.88 ns
SkipLast2Things10000010002,953,928.92 ns6,367.2951 ns5,955.9718 ns2,952,461.12 ns
SkipLast3Things10000010002,241,011.91 ns10,903.9357 ns10,199.5482 ns2,240,134.90 ns
SkipLast4Things10000010002,740,062.68 ns56,549.0378 ns165,848.5390 ns2,787,877.28 ns

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment