Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update performance test to produce same result for both tests #244

Merged
merged 1 commit into from
Sep 24, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 36 additions & 22 deletions stash/performance.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import std/[hashes, times]
import std/[hashes, times, monotimes]

#
# This is a performance comparison between CPS and native closure iterators.
Expand All @@ -11,58 +11,72 @@ when not defined(gcArc):

import cps

template howLong(what, code): float =
let start = cpuTime()
template howLong(what, code): Duration =
let start = getMonoTime()
block:
code
let duration = cpuTime() - start
echo what, ": ", duration, " s"
let duration = getMonoTime() - start
echo what, ": ", duration
duration


const iterations = 1_000_000_000
var h: Hash = 0

let t1 = howLong "cps iterator":

type
Iterator = ref object of Continuation
yielded: bool
val: int

proc jield(it: Iterator; val: int): Iterator {.cpsMagic.} =
it.yielded = true
it.val = val
return it

proc next(it: var Iterator): int =
while true:
it = Iterator it.fn(it)
if it.finished: break
if it.yielded:
it.yielded = false
return it.val

proc counter(lo: int, hi: int) {.cps: Iterator.} =
var i = lo
while i <= hi:
jield i
inc i

template finished(x: ref): bool = x == nil or x.fn == nil

var a = Iterator: whelp counter(1, iterations)
while not finished(a):
h = h !& hash(a.val)
a = Iterator a.fn(a)

while true:
let next = a.next()
if a.finished: break
h = h !& hash(next)

echo !$h
h = 0

let t2 = howLong "closure iterator":

iterator counter(lo: int, hi: int): int {.closure.} =
var i = lo
while i <= hi:
yield i
yield i
inc i
proc counter(lo: int, hi: int): iterator(): int =
result =
iterator (): int =
var i = lo
while i <= hi:
yield i
inc i

let f = counter
while not finished(f):
h = h !& hash(f(1, iterations))
let f = counter(1, iterations)
while true:
let next = f()
if f.finished: break
h = h !& hash(next)

echo !$h

echo "Nim closure iterators are ", t2 / t1, " times slower"
let ratio = t2.inNanoseconds.float / t1.inNanoseconds.float
if ratio < 1:
echo "Nim closure iterators are ", 1 / ratio, " times faster"
else:
echo "Nim closure iterators are ", ratio, " times slower"