Skip to content

Commit

Permalink
fix: not working perf improvement using memoization and broken test
Browse files Browse the repository at this point in the history
  • Loading branch information
Casper Bollen authored and Casper Bollen committed Oct 29, 2023
1 parent a79e4e8 commit 1ba0398
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ Apple M2 Max, 1 CPU, 12 logical and 12 physical cores
```
| Method | Mean | Error | StdDev |
|-------------------- |------------:|------------:|------------:|
| AllPairesInt_100 | 124.4 μs | 0.50 μs | 0.46 μs |
| AllPairsInt_200 | 740.2 μs | 4.20 μs | 3.93 μs |
| SolveCountMinIncl | 100.3 μs | 0.56 μs | 0.49 μs |
| Solve_1_Eqs_100 | 12,808.2 μs | 123.12 μs | 115.17 μs |
| Solve_1_Eqs_200 | 51,027.0 μs | 1,018.90 μs | 2,034.85 μs |
| Solve_3_Eqs_100 | 13,494.7 μs | 140.81 μs | 131.72 μs |
| Solve_3_Eqs_200 | 52,360.1 μs | 997.85 μs | 1,109.10 μs |
| Solve_1_Eqs_Rand_10 | 9,078.6 μs | 23.49 μs | 20.82 μs |
| Solve_1_Eqs_Rand_20 | 89,190.0 μs | 441.00 μs | 412.51 μs |
| Solve_3_Eqs_Rand_10 | 9,599.2 μs | 28.00 μs | 26.19 μs |
| Solve_3_Eqs_Rand_20 | 90,438.7 μs | 358.47 μs | 335.31 μs |
| Method | Mean | Error | StdDev |
|-------------------- |-------------:|-------------:|-------------:|
| AllPairesInt_100 | 124.16 μs | 0.235 μs | 0.208 μs |
| AllPairsInt_200 | 750.41 μs | 3.810 μs | 3.377 μs |
| SolveCountMinIncl | 97.92 μs | 1.198 μs | 1.120 μs |
| Solve_1_Eqs_100 | 12,788.84 μs | 134.926 μs | 126.210 μs |
| Solve_1_Eqs_200 | 50,817.55 μs | 1,013.622 μs | 2,093.306 μs |
| Solve_3_Eqs_100 | 13,385.99 μs | 81.075 μs | 75.838 μs |
| Solve_3_Eqs_200 | 51,935.72 μs | 993.614 μs | 1,182.827 μs |
| Solve_1_Eqs_Rand_10 | 9,183.25 μs | 27.803 μs | 26.007 μs |
| Solve_1_Eqs_Rand_20 | 88,937.43 μs | 55.626 μs | 46.450 μs |
| Solve_3_Eqs_Rand_10 | 9,415.45 μs | 19.153 μs | 16.978 μs |
| Solve_3_Eqs_Rand_20 | 94,196.45 μs | 260.758 μs | 231.155 μs |
98 changes: 50 additions & 48 deletions src/Informedica.GenSolver.Lib/Equation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -336,15 +336,60 @@ module Equation =
| y::xs ->
y |> op2 <| (xs |> List.reduce op1)
|> Some
// select the right application operator
let (<==) = if onlyMinIncrMax then (@<-) else (^<-)
// perform the calculations on the vars
let calcVars op1 op2 vars =
vars
|> List.fold (fun acc vars ->
if acc |> Option.isSome then acc
else
match vars with
| _, []
| _, [ _ ] -> acc
| i, y::xs ->
let op2 = if i = 0 then op1 else op2
// log starting the calculation
(op1, op2, y, xs)
|> Events.EquationStartCalculation
|> Logging.logInfo log

xs
|> calc op1 op2
|> function
| None ->
// log finishing the calculation
(y::xs, false)
|> Events.EquationFinishedCalculation
|> Logging.logInfo log

None
| Some var ->
let yNew = y <== var

if yNew <> y then
// log finishing the calculation
([yNew], true)
|> Events.EquationFinishedCalculation
|> Logging.logInfo log

Some yNew
else
// log finishing the calculation
([], false)
|> Events.EquationFinishedCalculation
|> Logging.logInfo log

None
) None

if eq |> isSolved then eq, Unchanged
else
// log starting the equation solve
eq
|> Events.EquationStartedSolving
|> Logging.logInfo log
// select the right application operator
let (<==) = if onlyMinIncrMax then (@<-) else (^<-)

// get the vars and the matching operators
let vars, op1, op2 =
match eq with
Expand All @@ -362,50 +407,6 @@ module Equation =
// a = b + d becomes a list representing
// [ a = b + d; b = a - d; d = a - b ]
let vars = vars |> reorder
// perform the calculations on the vars
let calcVars vars =
vars
|> List.fold (fun acc vars ->
if acc |> Option.isSome then acc
else
match vars with
| _, []
| _, [ _ ] -> acc
| i, y::xs ->
let op2 = if i = 0 then op1 else op2
// log starting the calculation
(op1, op2, y, xs)
|> Events.EquationStartCalculation
|> Logging.logInfo log

xs
|> calc op1 op2
|> function
| None ->
// log finishing the calculation
(y::xs, false)
|> Events.EquationFinishedCalculation
|> Logging.logInfo log

None
| Some var ->
let yNew = y <== var

if yNew <> y then
// log finishing the calculation
([yNew], true)
|> Events.EquationFinishedCalculation
|> Logging.logInfo log

Some yNew
else
// log finishing the calculation
([], false)
|> Events.EquationFinishedCalculation
|> Logging.logInfo log

None
) None
// loop until no changes are detected, i.e.
// calcVars returns None
let rec loop acc vars =
Expand All @@ -419,7 +420,7 @@ module Equation =
|> List.sumBy Variable.count
)

match calcVars vars with
match calcVars op1 op2 vars with
| None -> acc, vars
| Some var ->
vars
Expand All @@ -434,7 +435,8 @@ module Equation =
|> List.sortBy(fun (_, xs) ->
xs
|> List.tail
|> List.sumBy Variable.count
|> List.map Variable.count
|> List.reduce (*)
)
|> loop (acc |> List.replaceOrAdd (Variable.eqName var) var)

Expand Down
2 changes: 2 additions & 0 deletions src/Informedica.GenSolver.Lib/Scripts/Solver.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,5 @@ eqs
|> ignore
| Error _ -> failwith "errors"
|> ignore


32 changes: 4 additions & 28 deletions src/Informedica.GenSolver.Lib/Solver.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ namespace Informedica.GenSolver.Lib
/// equations
module Solver =

open System.Collections.Generic

module EQD = Equation.Dto
module Name = Variable.Name

Expand Down Expand Up @@ -80,25 +78,6 @@ module Solver =
, rst


/// <summary>
/// Create a memoized function
/// </summary>
/// <param name="f">The function to memoize</param>
/// <remarks>
/// This memoize function uses a Dictionary instead of
/// a map, because the Dictionary is faster. But Dictionary
/// cannot take Unit as a key!
/// </remarks>
let memSolve f =
let cache = Dictionary<_, _>()
fun e ->
if cache.ContainsKey(e) then cache[e]
else
let r = f e
cache.Add(e, r)
r


let sortQue onlyMinMax que =
if que |> List.length = 0 then que
else
Expand All @@ -111,6 +90,7 @@ module Solver =
/// and function to determine whether an
/// equation is solved
let solve onlyMinIncrMax log sortQue var eqs =

let solveE n eqs eq =
try
Equation.solve onlyMinIncrMax log eq
Expand All @@ -135,7 +115,7 @@ module Solver =
|> Exceptions.SolverTooManyLoops
|> Exceptions.raiseExc None []

let que = que |> sortQue
let que = que |> sortQue onlyMinIncrMax

//(n, que)
//|> Events.SolverLoopedQue
Expand Down Expand Up @@ -245,10 +225,8 @@ module Solver =
//TODO: need to clean up the number check
let solveVariable onlyMinIncrMax log sortQue vr eqs =
let n1 = eqs |> List.length
// TODO: need to test this using BenchmarkDotNet
let solve =
solve onlyMinIncrMax log (sortQue onlyMinIncrMax) None
|> memSolve
solve onlyMinIncrMax log sortQue (Some vr)

match solve eqs with
| Error (eqs, errs) -> Error (eqs, errs)
Expand All @@ -261,10 +239,8 @@ module Solver =
//TODO: need to clean up the number check
let solveAll onlyMinIncrMax log eqs =
let n1 = eqs |> List.length
// TODO: need to test this using BenchmarkDotNet
let solve =
solve onlyMinIncrMax log (sortQue onlyMinIncrMax) None
|> memSolve
solve onlyMinIncrMax log sortQue None

match solve eqs with
| Error (eqs, errs) -> Error (eqs, errs)
Expand Down
2 changes: 1 addition & 1 deletion tests/Informedica.GenSolver.Tests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ module TestSolver =

let solve n p eqs =
let n = n |> Name.createExc
Api.solve true id logger n p eqs
Api.solve true (fun _ eqs -> eqs) logger n p eqs

let solveAll = Api.solveAll false logger

Expand Down

0 comments on commit 1ba0398

Please sign in to comment.