Skip to content

Instantly share code, notes, and snippets.

@hyrmn
Created July 26, 2019 03:11
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 hyrmn/160fe639d4e5627be16fbeb4ae3b2cdf to your computer and use it in GitHub Desktop.
Save hyrmn/160fe639d4e5627be16fbeb4ae3b2cdf to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
[CoreJob]
//[MemoryDiagnoser]
//[InProcess()]
public class Strings
{
//For "find nearest"
private const int Entries = 20;
private const int StepSize = 60;
private static readonly int[] _acceptableSeconds =
Enumerable.Range(1, Entries).Select(seconds => seconds * StepSize).ToArray();
private static readonly string[] _fuckYouImATrain =
_acceptableSeconds.Select(seconds => $"public,max-age={seconds},must-revalidate").ToArray();
//For the dictionary lookup
private ConcurrentDictionary<int, string> LittleShopOfHorrors = new ConcurrentDictionary<int, string>();
//For LastCache
private int _lastSeconds = 3600;
private string _lastHeader = "public,max-age=3600,must-revalidate";
[Benchmark]
public string Literal() => "public,max-age=3600,must-revalidate";
[Benchmark(Baseline = true)]
[ArgumentsSource(nameof(PassingInts))]
public string BlingString(int seconds) => $"public,max-age={seconds},must-revalidate";
[Benchmark]
[ArgumentsSource(nameof(PassingInts))]
public string LookupDictionary(int seconds) =>
LittleShopOfHorrors.GetOrAdd(seconds, s => $"public,max-age={s},must-revalidate");
[Benchmark()]
[ArgumentsSource(nameof(PassingInts))]
public string LastCache(int seconds)
{
if (_lastSeconds != seconds)
{
_lastSeconds = seconds;
_lastHeader = $"public,max-age={seconds},must-revalidate";
}
return _lastHeader;
}
[Benchmark]
[ArgumentsSource(nameof(PassingInts))]
public string FindNearest(int seconds)
{
var idx = Array.BinarySearch(_acceptableSeconds, RoundToNearest(seconds, StepSize));
if (idx > -1)
return _fuckYouImATrain[idx];
return ~idx < Entries ? _fuckYouImATrain[~idx] : _fuckYouImATrain[Entries - 1];
}
private static int RoundToNearest(int value, int step) => ((value + (step / 2)) / step) * step;
[Benchmark]
[ArgumentsSource(nameof(PassingEnums))]
public string LiteralByChoice(CacheLengths cacheLength)
{
switch (cacheLength)
{
case CacheLengths.Short:
return "public,max-age=60,must-revalidate";
case CacheLengths.Medium:
return "public,max-age=3600,must-revalidate";
case CacheLengths.Long:
return "public,max-age=86400,must-revalidate";
default:
return "public,max-age=0";
}
}
public IEnumerable<int> PassingInts()
{
yield return 60;
yield return 60 * 60;
yield return 60 * 60 * 24;
}
public IEnumerable<CacheLengths> PassingEnums()
{
yield return CacheLengths.Short;
yield return CacheLengths.Medium;
yield return CacheLengths.Long;
}
public enum CacheLengths
{
Short = 60,
Medium = 60 * 60,
Long = 60 * 60 * 24
}
}
public class Program
{
public static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<Strings>();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment