7 ms·
EDIT: as pointed out, this is run with Guile 2.2, which is pre-JIT. Results to be posted later in this thread... Okay. $ cat fib.scm (define (fibonacc
by vitus 6y ago
EDIT: as pointed out, this is run with Guile 2.2, which is pre-JIT. Results to be posted later in this thread...
Okay.
$ cat fib.scm
(define (fibonacci n)
(if (<= n 1)
n
(+ (fibonacci (- n 1)) (fibonacci (- n 2)))))
(fibonacci 40)
$ time guile fib.scm
guile fib.scm 8.52s user 0.01s system 99% cpu 8.559 total
Node also uses V8.
$ time node fib.js
node fib.js 1.29s user 0.01s system 100% cpu 1.296 total
But okay, you wanted deno.
$ time deno run fib.js
deno run fib.js 1.41s user 0.02s system 99% cpu 1.423 total
Meanwhile, using `emacs --script fib.elc` to evaluate byte-compiled (fib 40) takes about 32s. And `emacs --script fib.el` takes about 2x that, at 64s.
edit: for reference, the equivalent C code runs in 0.27s on my laptop.
edit edit: okay, okay, compiling the Guile code before running it speeds it up to an exciting 8.16s execution time, still about 6x slower than deno.
- anthk 6y agoguile --version? EDIT: Guile3 brings JIT support... Guile always compiles code before running it, but adding a JIT it's only from v > 2.91.x, and by default at v3.
- vitus 6y agoAh. This is on Guile 2.2, apparently. Installing guile3 and rerunning...
- vitus 6y agoBetter, but still slower by about 1.5x. $ time guile3 fib.scm guile3 fib.scm 2.01s user 0.02s system 99% cpu 2.047 total edit: apparently my cpu was still being throttled post-build or something, as the initial runs were around 3s. Rerunning slightly later, it was noticeably faster.
- anthk 6y agoWell, not bad considering Guile3 and it's JIT are pretty early on release compared to the enormous work from a company as huge as Google with a full team working on v8 across years. Guile3 will improve that, too.
- eddieh 6y agoThis got me curious about other Scheme implementations. Chicken compiles to C $ csc fib.scm $ time ./fib real 0m8.461s user 0m8.383s sys 0m0.061s Racket has a modern JIT $ cat fib.rkt #lang racket (define (fibonacci n) (if (<= n 1) n (+ (fibonacci (- n 1)) (fibonacci (- n 2))))) (fibonacci 40) $ time racket fib.rkt 102334155 real 0m1.396s user 0m1.142s sys 0m0.127s For reference $ sysctl -a | grep .brand_string machdep.cpu.brand_string: Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
- taeric 6y agoThis got me interested in other lisps, as well. Looks like sbcl gives (time (fib 40)) to be about 1.7 seconds on my machine. (Ryzen 5 3600x.) For lulz, I clocked a dumb loop version. (defun fib (n) (loop repeat n for a = 1 then b for b = 1 then c for c = (+ a b) finally (return a))) And... well, serves as an amusing reminder that tree recursion has its downsides. :D Edit: I confess the speed of the loop got me curious and.... javascript has numeric overflow. That would be a hell of a surprise if you weren't expecting it. Edit2: (I realize overflow isn't the right term, but it is amusing that I can calc the 10000th fib in elisp... not so much in javascript. And yes, even elisp falls over sooner than sbcl does.)
- eddieh 6y agoTry BigInt in JS https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- taeric 6y agoApologies, I should have acknowledged there are ways to get around that today. My guess is most folks writing javascript are not aware of BigInt. And will only become so when it bites them. Granted, this is also true of fixednum in common lisp. At least "biting you" with that should only be performance. (I can't think of many other ways for that one to get you.) Edit: I should further ack that "getting around" it is as simple as adding "n" to one of the constants. So, it is nicely done.
- hvis 6y ago> Meanwhile, using `emacs --script fib.elc` to evaluate byte-compiled (fib 40) takes about 32s Which Emacs version is this? Any chance you want to try the native-comp branch and post its numbers here as well?
- vitus 6y agoThis was emacs 27.1 (which is the version in the Arch repo). I can install native-comp via AUR. It'll take some time.
- vitus 6y agoI think this is what you're looking for. time emacs --script fib-0b03fe9a-6b386e71.eln emacs --script fib-0b03fe9a-6b386e71.eln 22.47s user 0.09s system 99% cpu 22.664 total About 50% faster, which is nothing to sneeze at, but still appreciably slower than most other things I tried. (I copied the .eln from the cache to confirm that's what I'm running against; I got a similar speedup from running against fib.elc.)
- hvis 6y agoThank you. That's an interesting result.
- koral 6y agoAsking as wasn't mention, was fib compiled with comp-speed 3? That should be considerably relevant in this benchmark. PS you can also run a wider set of benchmarks to compare against stock Emacs using: https://elpa.gnu.org/packages/elisp-benchmarks.html https://elpa.gnu.org/packages/elisp-benchmarks.html Here some not very updated results: http://akrl.sdf.org/gccemacs.html#org4297f0f http://akrl.sdf.org/gccemacs.html#org4297f0f
- hvis 6y agoHi Andrea (right?), IIUC, you're saying the fib benchmark gets optimized out at speed 3 (and thus run faster than all the implementations discussed here). But what about speed 2, which is the current default? If we're 15 times slower on this benchmark, does that mean that Node has much cheaper function calls, or something like that? Because we have to keep Emacs Lisp functions advice-able (which I agree is a good thing)?