Created
June 10, 2021 07:38
-
-
Save planetis-m/10ba75324ecd7924e19816dc52f1cd4a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import eminim, std/[parsejson, streams] | |
type | |
Fruit = enum | |
Banana, Apple | |
Bar = object | |
shared: int | |
kind: Fruit | |
bad: float | |
banana: int | |
apple: string | |
OnceCtx = object | |
shared, kind, bad, banana, apple: bool | |
when defined(emiNextgen): | |
proc initFromJson(dst: var Bar, p: var JsonParser) = | |
var o: OnceCtx | |
eat(p, tkCurlyLe) | |
while p.tok != tkCurlyRi: | |
if p.tok != tkString: | |
raiseParseErr(p, "string literal as key") | |
case p.a | |
of "shared": | |
discard getTok(p) | |
eat(p, tkColon) | |
if not o.shared: | |
o.shared = true | |
initFromJson(dst.shared, p) | |
else: | |
when defined(emiDuplicateKey): skipJson(p) | |
else: raiseParseErr(p, "unique key") | |
of "kind": | |
discard getTok(p) | |
eat(p, tkColon) | |
if not o.kind: | |
o.kind = true | |
initFromJson(dst.kind, p) | |
else: | |
when defined(emiDuplicateKey): skipJson(p) | |
else: raiseParseErr(p, "unique key") | |
of "bad": | |
discard getTok(p) | |
eat(p, tkColon) | |
if not o.bad: | |
o.bad = true | |
initFromJson(dst.bad, p) | |
else: | |
when defined(emiDuplicateKey): skipJson(p) | |
else: raiseParseErr(p, "unique key") | |
of "banana": | |
discard getTok(p) | |
eat(p, tkColon) | |
if not o.banana: | |
o.banana = true | |
initFromJson(dst.banana, p) | |
else: | |
when defined(emiDuplicateKey): skipJson(p) | |
else: raiseParseErr(p, "unique key") | |
of "apple": | |
discard getTok(p) | |
eat(p, tkColon) | |
if not o.apple: | |
o.apple = true | |
initFromJson(dst.apple, p) | |
else: | |
when defined(emiDuplicateKey): skipJson(p) | |
else: raiseParseErr(p, "unique key") | |
else: | |
when defined(emiLenient): skipJson(p) | |
else: raiseParseErr(p, "valid object field") | |
if p.tok != tkComma: | |
break | |
discard getTok(p) | |
eat(p, tkCurlyRi) | |
import std / [times, stats, strformat,random] | |
const MaxIter = 1_000_000 | |
proc warmup() = | |
# Warmup - make sure cpu is on max perf | |
let start = cpuTime() | |
var a = 123 | |
for i in 0 ..< 300_000_000: | |
a += i * i mod 456 | |
a = a mod 789 | |
let dur = cpuTime() - start | |
echo &"Warmup: {dur:>4.4f} s ", a | |
proc printStats(name: string, stats: RunningStat, dur: float) = | |
echo &"""{name}: | |
Collected {stats.n} samples in {dur:>4.4f} s | |
Average time: {stats.mean * 1000:>4.4f} ms | |
Stddev time: {stats.standardDeviationS * 1000:>4.4f} ms | |
Min time: {stats.min * 1000:>4.4f} ms | |
Max time: {stats.max * 1000:>4.4f} ms""" | |
template bench(name, samples, code: untyped) = | |
var stats: RunningStat | |
let globalStart = cpuTime() | |
for i in 0 ..< samples: | |
let start = cpuTime() | |
code | |
let duration = cpuTime() - start | |
stats.push duration | |
let globalDuration = cpuTime() - globalStart | |
printStats(name, stats, globalDuration) | |
proc main = | |
randomize() | |
warmup() | |
var s = newStringStream(newStringOfCap(50*MaxIter)) | |
var data = newSeqOfCap[Bar](MaxIter) | |
for i in 0..<MaxIter: | |
data.add Bar(kind: if rand(1.0) <= 0.5: Banana else: Apple) | |
s.storeJson(data) | |
s.setPosition(0) | |
var | |
a: seq[Bar] | |
bench("emi", 1): | |
a = s.jsonTo(typeof data) | |
echo a[0..4] | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment