diff --git a/README.md b/README.md index e0bbe779..33701a9c 100644 --- a/README.md +++ b/README.md @@ -13,29 +13,35 @@ The title of this repository is a pun on two meanings of "time to": "how much ti - [x] Squiggle - [x] Javascript (NodeJS) - [x] C +- [x] Nim ## Performance table With the [time](https://man7.org/linux/man-pages/man1/time.1.html) tool, using 1M samples: -| Language | Time | -|----------|-----------| -| C | 0m0,442s | -| Node | 0m0,732s | -| Squiggle | 0m1,536s | -| R | 0m7,000s | -| Python (CPython) | 0m16,641s | +| Language | Time | +|----------------------|-----------| +| Nim | 0m0.183s | +| C | 0m0,442s | +| Node | 0m0,732s | +| Squiggle | 0m1,536s | +| R | 0m7,000s | +| Python (CPython) | 0m16,641s | +I was very surprised that Node/Squiggle code was almost as fast as the raw C code. For the Python code, it's possible that the lack of speed is more a function of me not being as familiar with Python. It's also very possible that the code would run faster with [PyPy](https://doc.pypy.org). + +I was also really happy with trying [Nim](https://nim-lang.org/). The version which beats all others is just the normal usage of Nim, in the "release" compilation mode (the "danger" compilation mode shaves of a few more miliseconds). The Nim version has the particularity that I define the normal function from scratch, using the [Box–Muller transform](https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform#Basic_form). For Nim I also have a version of the code which takes around 4 seconds, where I define some very inefficient sine & logarithm functions to feed into the Box-Muller method, because it felt like fun to really write a botec tool really from scratch. -I was very surprised that Node/Squiggle code was almost as fast as the raw C code. For the Python code, it's possible that the lack of speed is more a function of me not being as familiar with Python. It's also very possible that the code would run faster with [PyPy](https://doc.pypy.org) - ## Languages I may add later -- Julia (TuringML) -- Rust -- Lisp +- [ ] Julia (TuringML) +- [ ] Rust +- [ ] Lisp +- [ ] Stan +- [ ] Go +- [ ] Zig +- [ ] Forth - ... and suggestions welcome -- Stan ## Roadmap diff --git a/wip/nim/hardcore/README.md b/nim/hardcore/README.md similarity index 100% rename from wip/nim/hardcore/README.md rename to nim/hardcore/README.md diff --git a/wip/nim/hardcore/makefile b/nim/hardcore/makefile similarity index 100% rename from wip/nim/hardcore/makefile rename to nim/hardcore/makefile diff --git a/wip/nim/hardcore/samples b/nim/hardcore/samples similarity index 88% rename from wip/nim/hardcore/samples rename to nim/hardcore/samples index 502e20f0..a78befe4 100755 Binary files a/wip/nim/hardcore/samples and b/nim/hardcore/samples differ diff --git a/wip/nim/hardcore/samples.nim b/nim/hardcore/samples.nim similarity index 98% rename from wip/nim/hardcore/samples.nim rename to nim/hardcore/samples.nim index 60870b9a..a6c9fbab 100644 --- a/wip/nim/hardcore/samples.nim +++ b/nim/hardcore/samples.nim @@ -29,7 +29,7 @@ proc sine(x: float): float = ## Arithmetic-geomtric mean proc ag(x: float, y: float): float = - let n = 16 # just some high number + let n = 32 # just some high number var a = (x + y)/2.0 var b = sqrt(x * y) for i in 0..n: @@ -41,7 +41,7 @@ proc ag(x: float, y: float): float = ## Find m such that x * 2^m > 2^precision/2 proc find_m(x:float): float = var m = 0.0; - let precision = 32 # bits + let precision = 64 # bits let c = pow(2.0, precision.float / 2.0) while x * pow(2.0, m) < c: m = m + 1 diff --git a/wip/nim/hello_world/hello_world b/nim/hello_world/hello_world similarity index 100% rename from wip/nim/hello_world/hello_world rename to nim/hello_world/hello_world diff --git a/wip/nim/hello_world/hello_world.nim b/nim/hello_world/hello_world.nim similarity index 100% rename from wip/nim/hello_world/hello_world.nim rename to nim/hello_world/hello_world.nim diff --git a/wip/nim/hello_world/makefile b/nim/hello_world/makefile similarity index 100% rename from wip/nim/hello_world/makefile rename to nim/hello_world/makefile diff --git a/wip/nim/makefile b/nim/makefile similarity index 74% rename from wip/nim/makefile rename to nim/makefile index 16ac3211..2bdcc9ff 100644 --- a/wip/nim/makefile +++ b/nim/makefile @@ -8,4 +8,5 @@ run: samples ./samples $(VERBOSE) examine: samples - nim c $(VERBOSE) -d:release samples.nim && time ./samples $(VERBOSE) + nim c $(VERBOSE) -d:release samples.nim && time ./samples $(VERBOSE) && echo + nim c $(VERBOSE) -d:danger samples.nim && time ./samples $(VERBOSE) diff --git a/nim/samples b/nim/samples new file mode 100755 index 00000000..dd0e138d Binary files /dev/null and b/nim/samples differ diff --git a/wip/nim/samples.nim b/nim/samples.nim similarity index 100% rename from wip/nim/samples.nim rename to nim/samples.nim diff --git a/wip/nim/sums/makefile b/nim/sums/makefile similarity index 100% rename from wip/nim/sums/makefile rename to nim/sums/makefile diff --git a/wip/nim/sums/sums b/nim/sums/sums similarity index 100% rename from wip/nim/sums/sums rename to nim/sums/sums diff --git a/wip/nim/sums/sums.nim b/nim/sums/sums.nim similarity index 100% rename from wip/nim/sums/sums.nim rename to nim/sums/sums.nim diff --git a/time.txt b/time.txt index 88df2fba..37102e19 100644 --- a/time.txt +++ b/time.txt @@ -36,3 +36,18 @@ real 0m7,000s user 0m6,944s sys 0m0,052s +## Nim + +nim c --verbosity:0 -d:release samples.nim && time ./samples --verbosity:0 && echo +0.8873815480558296 + +real 0m0.183s +user 0m0.150s +sys 0m0.032s + +nim c --verbosity:0 -d:danger samples.nim && time ./samples --verbosity:0 +0.8886260086130379 + +real 0m0.157s +user 0m0.136s +sys 0m0.020s diff --git a/wip/nim/samples b/wip/nim/samples deleted file mode 100755 index 2522adef..00000000 Binary files a/wip/nim/samples and /dev/null differ