using System.Collections.Generic;
using System.Diagnostics;
public static void Main()
var sw = new Stopwatch();
Console.WriteLine("******************************************************");
Console.WriteLine("Example WITH multiple enumerations of the data source.");
Console.WriteLine("******************************************************\n");
var dataSource = DataSource.DataPoints;
var result = dataSource.Step1().Step2(1).Step3(5).Step4(1);
Console.WriteLine($"First item: {result.First()}");
Console.WriteLine($"It took {sw.Elapsed.Milliseconds} ms to execute the pipeline.");
Console.WriteLine("\n\n*********************************************************");
Console.WriteLine("Example WITHOUT multiple enumerations of the data source.");
Console.WriteLine("*********************************************************\n\n");
var anotherDataSource = DataSource.DataPoints;
var fasterResult = anotherDataSource.BetterStep1().BetterStep2(1).BetterStep3(5).BetterStep4(1);
Console.WriteLine($"First item: {fasterResult.First()}");
Console.WriteLine($"It took {sw.Elapsed.Milliseconds} ms to execute the pipeline.");
public static class MyBadPipeline
public static IEnumerable<int> Step1(this IEnumerable<int> data)
throw new Exception("Failed");
public static IEnumerable<int> Step2(this IEnumerable<int> data, int filterBottomThreshold)
return data.Where(t => t > filterBottomThreshold).ToList();
public static IEnumerable<int> Step3(this IEnumerable<int> data, int filterTopThreshold)
return data.Where(t => t < filterTopThreshold).ToList();
public static IEnumerable<int> Step4(this IEnumerable<int> data, int page)
return data.Skip(pageSize * page).Take(pageSize).ToList();
public static class ABetterPipeline
public static IEnumerable<int> BetterStep1(this IEnumerable<int> data)
public static IEnumerable<int> BetterStep2(this IEnumerable<int> data, int filterBottomThreshold)
return data?.Where(t => t > filterBottomThreshold);
public static IEnumerable<int> BetterStep3(this IEnumerable<int> data, int filterTopThreshold)
return data?.Where(t => t < filterTopThreshold);
public static IEnumerable<int> BetterStep4(this IEnumerable<int> data, int page)
return data?.Skip(pageSize * page).Take(pageSize);
public static class DataSource
private const string FILEPATH = "datadump.txt";
private const int DATASOURCE_SIZE = 100000;
public static IEnumerable<int> DataPoints
private static IEnumerable<int> GetDataPoints()
Console.WriteLine("\nRetrieving data...\n");
return File.ReadAllLines(FILEPATH).Select(int.Parse);
private static void GenerateData()
var data = Enumerable.Range(0, DATASOURCE_SIZE).Select(r => rand.Next(10).ToString());
File.WriteAllLines(FILEPATH, data);