Bench (#14)
All checks were successful
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/push/all-checks-complete Pipeline was successful

Co-authored-by: Smaug123 <patrick+github@patrickstevens.co.uk>
Reviewed-on: #14
This commit is contained in:
2023-12-12 21:03:49 +00:00
parent 4e97a4d454
commit 362a73cc41
6 changed files with 402 additions and 9 deletions

View File

@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Run.fs" />
<Compile Include="Inputs.fs" />
<Compile Include="Program.fs"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.11" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AdventOfCode2023.FSharp.Lib\AdventOfCode2023.FSharp.Lib.fsproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,19 @@
namespace AdventOfCode2023
open System.IO
open System.Reflection
[<RequireQualifiedAccess>]
module Inputs =
let days =
let mutable dir = Assembly.GetEntryAssembly().Location |> FileInfo |> _.Directory
while not (dir.EnumerateDirectories () |> Seq.exists (fun i -> i.Name = "inputs")) do
dir <- dir.Parent
if isNull dir then
failwith "reached root of filesystem without finding inputs dir"
Array.init 12 (fun day -> Path.Combine (dir.FullName, "inputs", $"day%i{day + 1}.txt") |> File.ReadAllText)
let inline day (i : int) = days.[i - 1]

View File

@@ -0,0 +1,70 @@
namespace AdventOfCode2023
open BenchmarkDotNet.Attributes
open BenchmarkDotNet.Configs
open BenchmarkDotNet.Running
module Benchmarks =
type Benchmark1To5 () =
[<GlobalSetup>]
member _.Setup () = Run.shouldWrite <- false
[<Params(1, 2, 3, 4, 5)>]
member val Day = 0 with get, set
[<Params(false, true)>]
member val IsPartOne = false with get, set
[<Benchmark>]
member this.Benchmark () : unit =
Run.allRuns.[this.Day - 1] (not this.IsPartOne) (Inputs.day this.Day)
[<GlobalCleanup>]
member _.Cleanup () = Run.shouldWrite <- true
type Benchmark6To10 () =
[<GlobalSetup>]
member _.Setup () = Run.shouldWrite <- false
[<Params(6, 7, 8, 9, 10)>]
member val Day = 0 with get, set
[<Params(false, true)>]
member val IsPartOne = false with get, set
[<Benchmark>]
member this.Benchmark () : unit =
Run.allRuns.[this.Day - 1] (not this.IsPartOne) (Inputs.day this.Day)
[<GlobalCleanup>]
member _.Cleanup () = Run.shouldWrite <- true
type Benchmark11To15 () =
[<GlobalSetup>]
member _.Setup () = Run.shouldWrite <- false
[<Params(11, 12)>]
member val Day = 0 with get, set
[<Params(false, true)>]
member val IsPartOne = false with get, set
[<Benchmark>]
member this.Benchmark () : unit =
Run.allRuns.[this.Day - 1] (not this.IsPartOne) (Inputs.day this.Day)
[<GlobalCleanup>]
member _.Cleanup () = Run.shouldWrite <- true
module Program =
[<EntryPoint>]
let main args =
let config =
ManualConfig.Create(DefaultConfig.Instance).WithOptions ConfigOptions.DisableOptimizationsValidator
let _summary = BenchmarkRunner.Run<Benchmarks.Benchmark1To5> config
let _summary = BenchmarkRunner.Run<Benchmarks.Benchmark6To10> config
let _summary = BenchmarkRunner.Run<Benchmarks.Benchmark11To15> config
0

View File

@@ -0,0 +1,190 @@
namespace AdventOfCode2023
#if DEBUG
#else
#nowarn "9"
#endif
open System
[<RequireQualifiedAccess>]
module Run =
let mutable shouldWrite = true
let day1 (partTwo : bool) (input : string) =
if not partTwo then
let output = Day1.part1 input
if shouldWrite then
Console.WriteLine output
else
let output = Day1.part2 input
if shouldWrite then
Console.WriteLine output
let day2 (partTwo : bool) (input : string) =
if not partTwo then
let output = Day2.part1 input
if shouldWrite then
Console.WriteLine output
else
let output = Day2.part2 input
if shouldWrite then
Console.WriteLine output
let day3 (partTwo : bool) (input : string) =
let resultArr, len, lineCount = Day3.parse (input.ToCharArray () |> Array.map byte)
#if DEBUG
let contents =
{
Elements = Array.take len resultArr
Width = len / lineCount
}
#else
use ptr = fixed resultArr
let contents =
{
Elements = ptr
Length = len
Width = len / lineCount
}
#endif
if not partTwo then
let output = Day3.part1 contents
if shouldWrite then
Console.WriteLine output
else
let output = Day3.part2 contents
if shouldWrite then
Console.WriteLine output
let day4 (partTwo : bool) (input : string) =
if not partTwo then
let output = Day4.part1 input
if shouldWrite then
Console.WriteLine output
else
let output = Day4.part2 input
if shouldWrite then
Console.WriteLine output
let day5 (partTwo : bool) (input : string) =
if not partTwo then
let output = Day5.part1 input
if shouldWrite then
Console.WriteLine output
else
let output = Day5.part2 input
if shouldWrite then
Console.WriteLine output
let day6 (partTwo : bool) (input : string) =
if not partTwo then
let output = Day6.part1 input
if shouldWrite then
Console.WriteLine output
else
let output = Day6.part2 input
if shouldWrite then
Console.WriteLine output
let day7 (partTwo : bool) (input : string) =
if not partTwo then
let output = Day7.part1 input
if shouldWrite then
Console.WriteLine output
else
let output = Day7.part2 input
if shouldWrite then
Console.WriteLine output
let day8 (partTwo : bool) (input : string) =
if not partTwo then
let output = Day8.part1 input
if shouldWrite then
Console.WriteLine output
else
let output = Day8.part2 input
if shouldWrite then
Console.WriteLine output
let day9 (partTwo : bool) (input : string) =
if not partTwo then
let output = Day9.part1 input
if shouldWrite then
Console.WriteLine output
else
let output = Day9.part2 input
if shouldWrite then
Console.WriteLine output
let day10 (partTwo : bool) (input : string) =
if not partTwo then
let output = Day10.part1 input
if shouldWrite then
Console.WriteLine output
else
let output = Day10.part2 input
if shouldWrite then
Console.WriteLine output
let day11 (partTwo : bool) (input : string) =
if not partTwo then
let output = Day11.part1 input
if shouldWrite then
Console.WriteLine output
else
let output = Day11.part2 input
if shouldWrite then
Console.WriteLine output
let day12 (partTwo : bool) (input : string) =
if not partTwo then
let output = Day12.part1 input
if shouldWrite then
Console.WriteLine output
else
let output = Day12.part2 input
if shouldWrite then
Console.WriteLine output
let allRuns =
[|
day1
day2
day3
day4
day5
day6
day7
day8
day9
day10
day11
day12
|]

View File

@@ -6,6 +6,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Test", "Test\Test.fsproj",
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "AdventOfCode2023.FSharp.Lib", "AdventOfCode2023.FSharp.Lib\AdventOfCode2023.FSharp.Lib.fsproj", "{95CE0568-3D1A-4060-BB54-52460FB1E399}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "AdventOfCode2023.FSharp.Bench", "AdventOfCode2023.FSharp.Bench\AdventOfCode2023.FSharp.Bench.fsproj", "{5FD3221D-2C90-4173-8FC0-90553CEE1D4A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -24,5 +26,9 @@ Global
{95CE0568-3D1A-4060-BB54-52460FB1E399}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95CE0568-3D1A-4060-BB54-52460FB1E399}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95CE0568-3D1A-4060-BB54-52460FB1E399}.Release|Any CPU.Build.0 = Release|Any CPU
{5FD3221D-2C90-4173-8FC0-90553CEE1D4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5FD3221D-2C90-4173-8FC0-90553CEE1D4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5FD3221D-2C90-4173-8FC0-90553CEE1D4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5FD3221D-2C90-4173-8FC0-90553CEE1D4A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal