Skip to content

Commit

Permalink
Speed up list generation
Browse files Browse the repository at this point in the history
fix type errors in tests
  • Loading branch information
Release-Candidate committed Apr 26, 2021
1 parent 2126404 commit 2b2469a
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 42 deletions.
40 changes: 24 additions & 16 deletions src/TzolkinDate/Generics.fs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ module Generics=
let dayDiff = if tzolkinDate - startTzolkin = 0 then cycleLength else tzolkinDate - startTzolkin
start + TimeSpan.FromDays (float dayDiff)

/// Add a gregorian date of a Tzolk’in day to the given list, to a length of `length`.
let rec private addDate getTzolkin length num start list =
let next = getTzolkin start
let nextNum = num + 1
if nextNum < length
then addDate getTzolkin length nextNum next (next :: list)
else List.rev (next :: list)
///// Add a gregorian date of a Tzolk’in day to the given list, to a length of `length`.
//let rec private addDate getTzolkin length num start list =
// let next = getTzolkin start
// let nextNum = num + 1
// if nextNum < length
// then addDate getTzolkin length nextNum next (next :: list)
// else List.rev (next :: list)

/// Return the last Gregorian date before or the same as `start` with a Tzolk’in
/// day of `tzolkinDate`.
Expand All @@ -62,20 +62,28 @@ module Generics=
if last = start then last + TimeSpan.FromDays (float -cycleLength) else last

/// Helper function.
let inline private getList getFunc referenceDate cycleLength numDates tzolkinDate start =
let rec getNextTzolkin = addDate (getFunc referenceDate cycleLength tzolkinDate) numDates
//let inline private getList getFunc referenceDate cycleLength numDates tzolkinDate start =
// let rec getNextTzolkin = addDate (getFunc referenceDate cycleLength tzolkinDate) numDates

getNextTzolkin 0 start []
// getNextTzolkin 0 start []

/// Return a list of gregorian dates with the given Tzolk’in date.
let inline internal getNextList referenceDate cycleLength numDates tzolkinDate start =
getList getNext referenceDate cycleLength numDates tzolkinDate start
let first = getNext referenceDate cycleLength tzolkinDate start
[ for idx in 0. .. float (numDates - 1) -> first + TimeSpan.FromDays (idx * float cycleLength) ]


/// Return a list of gregorian dates with the given Tzolk’in date.
//let inline internal getLastList referenceDate cycleLength numDates tzolkinDate start =
// let lastList = getList getLast referenceDate cycleLength numDates tzolkinDate start
// if tzolkinDate = fromDate referenceDate start then
// start :: lastList
// else
// lastList

let inline internal getLastList referenceDate cycleLength numDates tzolkinDate start =
let lastList = getList getLast referenceDate cycleLength numDates tzolkinDate start
if tzolkinDate = fromDate referenceDate start then
start :: lastList
else
lastList
let first = if tzolkinDate = fromDate referenceDate start then
start
else
getLast referenceDate cycleLength tzolkinDate start
[ for idx in 0. .. float (numDates - 1) -> first - TimeSpan.FromDays (idx * float cycleLength) ]
9 changes: 4 additions & 5 deletions src/TzolkinDate/TzolkinDate.fs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ module TzolkinDate =

/// Add days to a `TzolkinDate`, order of `int` and `TzolkinDate` changed.
static member ( + ) (i: int, tzolkinDate) =
{ Number = tzolkinDate.Number + i
Glyph = tzolkinDate.Glyph + i }
{ Number = i + tzolkinDate.Number
Glyph = i + tzolkinDate.Glyph }

/// Add two `TzolkinDate`. Doesn't really make sense, what would that be
/// conceptually? But define it anyway.
Expand All @@ -78,9 +78,8 @@ module TzolkinDate =
/// `TzolkinDate`.
/// Only makes sense with (at least) days, not hours, minutes, or seconds.
static member ( + ) (timeSpan: System.TimeSpan, tzolkinDate) =
{ Number = tzolkinDate.Number + timeSpan.Days
Glyph = tzolkinDate.Glyph + timeSpan.Days }

{ Number = timeSpan.Days + tzolkinDate.Number
Glyph = timeSpan.Days + tzolkinDate.Glyph }

/// A map of all 260 Tzolk’in days in a year.
/// The key is the number of the `TzolkinDate` in the Tzolk’in year, a number
Expand Down
18 changes: 10 additions & 8 deletions src/TzolkinDate/TzolkinGlyph.fs
Original file line number Diff line number Diff line change
Expand Up @@ -305,31 +305,33 @@ module TzolkinGlyph =
| (TzolkinGlyph n) -> n

/// Add two `TzolkinGlyph`.
static member ( + ) (glyph1:T, glyph2:T) =
static member ( + ) (glyph1: T, glyph2: T) =
int glyph1 + int glyph2
|> modulo20
|> TzolkinGlyph

/// Add an int to a `TzolkinGlyph`.
static member ( + ) (glyph1:T, i:int) =
int glyph1 + i
static member ( + ) (glyph1: T, i: int) =
let (TzolkinGlyph tz1) = glyph1
tz1 + i
|> modulo20
|> TzolkinGlyph

/// Add a `TzolkinGlyph` to an int.
static member ( + ) (i:int, glyph1:T) =
int glyph1 + i
static member ( + ) (i: int, glyph1: T) =
let (TzolkinGlyph tz1) = glyph1
i + tz1
|> modulo20
|> TzolkinGlyph

/// Add a `TimeSpan` to a `TzolkinGlyph`.
static member ( + ) (glyph1:T, days:TimeSpan) =
static member ( + ) (glyph1: T, days: TimeSpan) =
int glyph1 + days.Days
|> modulo20
|> TzolkinGlyph

/// Add a `TzolkinGlyph` to a `TimeSpan`.
static member ( + ) (days:TimeSpan, glyph:T) =
static member ( + ) (days: TimeSpan, glyph: T) =
days.Days + int glyph
|> modulo20
|> TzolkinGlyph
Expand Down Expand Up @@ -364,7 +366,7 @@ module TzolkinGlyph =

type T with
/// Subtract two `TzolkinGlyph`.
static member ( - ) (tz1:T, tz2:T) =
static member ( - ) (tz1: T, tz2: T) =
let day1 = int tz1
let day2 = int tz2
if day1 > day2 then
Expand Down
2 changes: 1 addition & 1 deletion src/TzolkinDate/TzolkinNumber.fs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ module TzolkinNumber =

/// Add a `TzolkinNumber` to an int.
static member ( + ) (i: int, tz1: T) =
int tz1 + i
i + int tz1
|> modulo13
|> TzolkinNumber

Expand Down
34 changes: 29 additions & 5 deletions tests/TestTzolkin/Generic.fs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,31 @@ module Generic=
endSize = 1000000 }

let configList = { FsCheckConfig.defaultConfig with
maxTest = 25
maxTest = 15
endSize = 500 }

let configFasterThan = { FsCheckConfig.defaultConfig with
maxTest = 100
endSize = 1000000 }

// Rules to calculate with `TzolkinNumber` and `TzolkinGlyph`. =================================

let inline testCommutativityType constructor i j =
let tzolkin1 = constructor i
let tzolkin2 = constructor j
match tzolkin1, tzolkin2 with
| None, _ -> test <@ i < 1 @>
| _, None -> test <@ j < 1 @>
| Some tz1, Some tz2 -> test <@ tz1 + tz2 = tz2 + tz1 @>

let inline testCommutativityTypeDate constructor i j k l =
let tzolkin1 = constructor i j
let tzolkin2 = constructor k l
match tzolkin1, tzolkin2 with
| None, _ -> test <@ i < 1 || j < 1 @>
| _, None -> test <@ k < 1 || l < 1 @>
| Some tz1, Some tz2 -> test <@ tz1 + tz2 = tz2 + tz1 @>

let inline testCommutativity constructor i days =
let tzolkin = constructor i
match tzolkin with
Expand Down Expand Up @@ -125,6 +145,7 @@ module Generic=
let inline stringList2DateList constructor list =
List.map (fun (date, tzolkin) -> stringToDate date, constructor tzolkin) list

// Test fromDate ===============================================================================
let inline testFromDate fromDate referenceDates =
let testFromDateHelper (fromDate: DateTime -> 'T) referenceDate date =
test <@ fromDate date = referenceDate @>
Expand All @@ -133,6 +154,7 @@ module Generic=
let date, tzolkin = elem
testFromDateHelper fromDate tzolkin date) referenceDates

// Test getNext and getLast ====================================================================
let inline testNextDate nextDate cycleLength referenceDates isLast =
let testNextDateHelper2 nextDate cycleLength referenceDate days isLast =
let (date:DateTime), tzolkin = referenceDate
Expand All @@ -152,7 +174,7 @@ module Generic=
referenceDates
|> List.iter (fun elem -> testNextDateHelper1 nextDate cycleLength elem isLast)


// Test getNextList and getLastList ============================================================
let inline testNextList nextDateList fromDate numDates cycleLength referenceDates isLast =
let rec testList list fromDate tzolkin difference =
match list with
Expand All @@ -167,15 +189,17 @@ module Generic=
let (date:DateTime), tzolkin = referenceDate
let start = date + TimeSpan.FromDays (float days)
let listToTest: DateTime list = nextDateList numDates tzolkin start
if isLast then
match listToTest, isLast with
| [], _ -> test <@ numDates = 0 @>
| _, true ->
test <@ listToTest.Head = date @>
testList listToTest fromDate tzolkin (float -cycleLength)
else
| _, false ->
test <@ listToTest.Head = date + TimeSpan.FromDays (float cycleLength) @>
testList listToTest fromDate tzolkin (float cycleLength)

let testNextListHelper1 numDates fromDate nextDateList cycleLength referenceDate isLast =
Gen.choose (0, cycleLength - 1) |> Gen.sample 0 5
Gen.choose (0, cycleLength - 1) |> Gen.sample 0 10
|> List.iter (fun i -> testNextListHelper2 fromDate numDates nextDateList cycleLength referenceDate i isLast)

referenceDates
Expand Down
28 changes: 25 additions & 3 deletions tests/TestTzolkin/TestTzolkinDate.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace TestTzolkin
open Expecto
open System


open RC.Maya


Expand Down Expand Up @@ -54,8 +55,12 @@ module TestTzolkinDate=
let tests =
testList
"TzolkinDate"
[ testPropertyWithConfig config "addition with int is commutative"
<| fun i j k ->
[ testPropertyWithConfig config "addition is commutative"
<| fun i j k l ->
testCommutativityTypeDate TzolkinDate.fromInts i j k l

testPropertyWithConfig config "addition with int is commutative"
<| fun i j (k: int) ->
testCommutativityDate TzolkinDate.fromInts i j k

testPropertyWithConfig config "addition with TimeSpan is commutative"
Expand All @@ -71,7 +76,7 @@ module TestTzolkinDate=
testNeutralElementDate TzolkinDate.fromInts i j (TimeSpan.FromDays 0.)

testPropertyWithConfig config "addition is associative with int"
<| fun i j k l ->
<| fun i j (k: int) (l: int) ->
testAssociativityDate TzolkinDate.fromInts i j k l

testPropertyWithConfig config "addition is associative with TimeSpan"
Expand Down Expand Up @@ -106,6 +111,23 @@ module TestTzolkinDate=
<| fun _ ->
testNextDate TzolkinDate.getLast 260 referenceDates true

//testPropertyWithConfig config "getNextList2 is faster"
//<| fun i ->
// Expect.isFasterThan (fun () ->
// let date, tzolkin = referenceDates.Head
// TzolkinDate.getNextList2
// (abs i)
// tzolkin
// date )
// (fun () ->
// let date, tzolkin = referenceDates.Head
// TzolkinDate.getNextList
// (abs i)
// tzolkin
// date )
//
// "getNextList2 is faster"

testPropertyWithConfig configList "getNextList with a reference date list"
<| fun i ->
testNextList
Expand Down
26 changes: 24 additions & 2 deletions tests/TestTzolkin/TestTzolkinGlyph.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ namespace TestTzolkin

open Expecto
open System
open FsCheck
open Swensen.Unquote

open RC.Maya



[<AutoOpen>]
module TestTzolkinGlyph=

Expand Down Expand Up @@ -46,10 +49,29 @@ module TestTzolkinGlyph=
let tests =
testList
"TzolkinGlyph"
[ testPropertyWithConfig config "addition with int is commutative"
[ testPropertyWithConfig config "addition is commutative"
<| fun i j ->
testCommutativityType TzolkinGlyph.create i j

testPropertyWithConfig config "addition with int is commutative"
<| fun i (j: int) ->
testCommutativity TzolkinGlyph.create i j

//testPropertyWithConfig config "addition with int is faster than timespan"
//<| fun i j ->
// Expect.isFasterThan (fun () ->
// Gen.choose (1, 1000) |> Gen.sample 0 10000
// |> List.iter (fun elem ->
// (TzolkinGlyph.T.TzolkinGlyph i) + elem |> ignore)
// )
// (fun () ->
// Gen.choose (1, 1000) |> Gen.sample 0 10000
// |> List.iter (fun elem ->
// (TzolkinGlyph.T.TzolkinGlyph i) +
// TimeSpan.FromDays (float elem) |> ignore )
// )
// "int is faster than TimeSpan"

testPropertyWithConfig config "addition with TimeSpan is commutative"
<| fun i j ->
testCommutativity TzolkinGlyph.create i (TimeSpan.FromDays (float j))
Expand All @@ -63,7 +85,7 @@ module TestTzolkinGlyph=
testNeutralElement TzolkinGlyph.create i (TimeSpan.FromDays 0.)

testPropertyWithConfig config "addition is associative with int"
<| fun i j k ->
<| fun i (j: int) (k: int) ->
testAssociativity TzolkinGlyph.create i j k

testPropertyWithConfig config "addition is associative with TimeSpan"
Expand Down
8 changes: 6 additions & 2 deletions tests/TestTzolkin/TestTzolkinNumber.fs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ module TestTzolkinNumber=
let tests =
testList
"TzolkinNumber"
[ testPropertyWithConfig config "addition with int is commutative"
[ testPropertyWithConfig config "addition is commutative"
<| fun i j ->
testCommutativityType TzolkinNumber.create i j

testPropertyWithConfig config "addition with int is commutative"
<| fun i (j: int) ->
testCommutativity TzolkinNumber.create i j

testPropertyWithConfig config "addition with TimeSpan is commutative"
Expand All @@ -64,7 +68,7 @@ module TestTzolkinNumber=
testNeutralElement TzolkinNumber.create i (TimeSpan.FromDays 0.)

testPropertyWithConfig config "addition is associative with int"
<| fun i j k ->
<| fun i j (k: int) ->
testAssociativity TzolkinNumber.create i j k

testPropertyWithConfig config "addition is associative with TimeSpan"
Expand Down

0 comments on commit 2b2469a

Please sign in to comment.