Bench
This commit is contained in:
@@ -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>
|
@@ -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]
|
@@ -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
|
190
AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Bench/Run.fs
Normal file
190
AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Bench/Run.fs
Normal 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
|
||||
|]
|
@@ -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
|
||||
|
104
README.md
104
README.md
@@ -7,23 +7,109 @@
|
||||
Ahead-of-time compiled with `PublishAot`, M1 Max.
|
||||
The format is: "answer part1\ntime\nanswer part2\ntime\n...", with possible extra lines indicating how long it took to parse the input if I happen to have split that out.
|
||||
|
||||
After day 3:
|
||||
BenchmarkDotNet:
|
||||
|
||||
```
|
||||
| Day | IsPartOne | Mean | Error | StdDev |
|
||||
|---- |---------- |----------:|---------:|---------:|
|
||||
| 1 | True | 10.23 us | 0.036 us | 0.032 us |
|
||||
| 1 | False | 17.93 us | 0.203 us | 0.180 us |
|
||||
| 2 | True | 17.39 us | 0.080 us | 0.075 us |
|
||||
| 2 | False | 25.42 us | 0.155 us | 0.145 us |
|
||||
| 3 | True | 65.60 us | 0.393 us | 0.328 us |
|
||||
| 3 | False | 145.52 us | 0.256 us | 0.200 us |
|
||||
| 4 | True | 109.78 us | 0.236 us | 0.209 us |
|
||||
| 4 | False | 110.34 us | 0.081 us | 0.063 us |
|
||||
| 5 | True | 13.44 us | 0.045 us | 0.042 us |
|
||||
| 5 | False | 61.70 us | 0.199 us | 0.177 us |
|
||||
|
||||
| Day | IsPartOne | Mean | Error | StdDev |
|
||||
|---- |---------- |---------------:|------------:|------------:|
|
||||
| 6 | True | 314.7 ns | 1.87 ns | 1.65 ns |
|
||||
| 6 | False | 316.3 ns | 0.31 ns | 0.26 ns |
|
||||
| 7 | True | 89,256.3 ns | 578.24 ns | 540.88 ns |
|
||||
| 7 | False | 95,062.7 ns | 921.75 ns | 862.21 ns |
|
||||
| 8 | True | 423,461.0 ns | 7,218.95 ns | 6,752.61 ns |
|
||||
| 8 | False | 2,045,302.1 ns | 4,338.61 ns | 3,846.06 ns |
|
||||
| 9 | True | 1,390,976.2 ns | 2,171.39 ns | 1,813.21 ns |
|
||||
| 9 | False | 2,173,468.1 ns | 3,171.04 ns | 2,647.96 ns |
|
||||
| 10 | True | 57,460.7 ns | 1,135.45 ns | 2,160.31 ns |
|
||||
| 10 | False | 694,553.9 ns | 2,935.74 ns | 2,746.09 ns |
|
||||
|
||||
| Day | IsPartOne | Mean | Error | StdDev | Median |
|
||||
|---- |---------- |----------:|----------:|----------:|----------:|
|
||||
| 11 | True | 39.085 ms | 0.0355 ms | 0.0297 ms | 39.082 ms |
|
||||
| 11 | False | 38.608 ms | 0.0270 ms | 0.0211 ms | 38.617 ms |
|
||||
| 12 | True | 1.846 ms | 0.0044 ms | 0.0041 ms | 1.845 ms |
|
||||
| 12 | False | 18.692 ms | 0.3676 ms | 0.3775 ms | 18.962 ms |
|
||||
```
|
||||
|
||||
After day 12, a single run of the ahead-of-time compiled version:
|
||||
|
||||
```
|
||||
=====Day 1=====
|
||||
54304
|
||||
0.549458ms
|
||||
3.418417ms
|
||||
54418
|
||||
0.710375ms
|
||||
0.317958ms
|
||||
=====Day 2=====
|
||||
2727
|
||||
0.119959ms
|
||||
0.079917ms
|
||||
56580
|
||||
0.155708ms
|
||||
0.1395ms parse
|
||||
0.107292ms
|
||||
=====Day 3=====
|
||||
0.140292ms parse
|
||||
540131
|
||||
0.1395ms
|
||||
0.140292ms
|
||||
86879020
|
||||
0.840791ms
|
||||
4.144166ms total
|
||||
0.664416ms
|
||||
=====Day 4=====
|
||||
27454
|
||||
0.390541ms
|
||||
6857330
|
||||
0.360375ms
|
||||
=====Day 5=====
|
||||
806029445
|
||||
0.161917ms
|
||||
59370572
|
||||
0.249708ms
|
||||
=====Day 6=====
|
||||
32076
|
||||
0.002917ms
|
||||
34278221
|
||||
0.001667ms
|
||||
=====Day 7=====
|
||||
250058342
|
||||
0.409792ms
|
||||
250506580
|
||||
0.431167ms
|
||||
=====Day 8=====
|
||||
19199
|
||||
1.192792ms
|
||||
13663968099527
|
||||
5.276083ms
|
||||
=====Day 9=====
|
||||
1898776583
|
||||
3.775667ms
|
||||
1100
|
||||
5.365875ms
|
||||
=====Day 10=====
|
||||
6842
|
||||
0.201208ms
|
||||
393
|
||||
2.226042ms
|
||||
=====Day 11=====
|
||||
0.11225ms parse
|
||||
9947476
|
||||
48.423ms
|
||||
519939907614
|
||||
34.836125ms
|
||||
=====Day 12=====
|
||||
7402
|
||||
4.704375ms
|
||||
3384337640277
|
||||
31.825583ms
|
||||
151.644334ms total
|
||||
```
|
||||
|
||||
# Building yourself
|
||||
|
Reference in New Issue
Block a user