Re: Estimation of π using Leibniz series
Using exponentiation just for interlacing 1, -1, 1, -1, ... is pointless (apart from mathematical formulas on paper) and should not be done, so no matter if some compiler optimizes it.
Re: Nim in Action is now officially in print!
My copy just arrived today. Will start to read it later today.
Re: Estimation of π using Leibniz series
@zolern : I'm wondering too why the original nim version is that slow. Using the windows version of nim on my computer (i7-6650, 3.60GHz, Windows 10 Pro 64-bit) is already faster at running my version of the program (see below) then running it under _windows/bash/ubuntu_ (what I did before). The same is true for the _Julia_ version. Using _clang_ instead of _gcc_ makes it almost 3x faster. Since _Julia_ is using _LLVM_, probably the _clang_ version uses the same (faster?) library functions. I'm not sure ... **clang version on windows/mingw**: nim c -r -d:release --cc:clang pi.nim ... Elapsed time: 2.055 Pi: 3.141592663589326 **gcc version on windows/mingw**: nim c -r -d:release pi.nim ... Elapsed time: 5.909 Pi: 3.141592663589326 **pi.nim**: import times, math proc `/`(a, b: int): float = float(a) / float(b) proc leibniz(terms: int): float = for i in 0 .. terms: result += ((-1)^i) / (2*i+1) result *= 4.0 let t0 = cpuTime() pi = leibniz(100_000_000) tt = cpuTime() - t0 echo("Elapsed time: ", tt) echo("Pi: ", pi)
Re: Estimation of π using Leibniz series
I am still confused that Nim's pow is so unexpectedly slow: Nim just calls C library function pow from , wtf? Anyway, last edition (without pow) is just fast & furious And Nim is awesome, no doubt!
Re: Estimation of π using Leibniz series
Our **lovely Nim** is outstanding !
Re: Nim in Action is now officially in print!
Well as I found out, my Book is on the way, too. Yay. Well you did not get my feedback during the development of the Book, but I think you will get my feedback when I read it. Then you can use it for revision 1
Re: Practice code.
Write a game
Re: Nim in Action is now officially in print!
Wow, final "ready for print" edition is pretty awesome. Great work!
Re: Estimation of π using Leibniz series
I am pretty sure that Julias's POW takes care that first argument is -1 and optimized it with something like MOD You can check it, I suppose that modified Julia code with MOD will take pretty same time as code with POW.
Re: Estimation of π using Leibniz series
@zolern, thank you. Your code rocks. However, we are cheating Julia because in her code there is a **POW** instead **MOD**. I will modify / rerun the .jl script just to check the result.
Re: Estimation of π using Leibniz series
Well, my 10 cents import times, math proc leibniz(terms: int): float = var res = 0.0 for n in 0..terms: res = res + (if n mod 2 == 0: 1.0 else: -1.0) / float(2 * n + 1) return 4*res let t0 = cpuTime() echo(leibniz(100_000_000)) let t1 = cpuTime() echo "Elapsed time: ", $(t1 - t0) * With -d:release compile option: 0.381 seconds * Without -d:release: 2.711 seconds Original "pow" version: * With -d:release: 7.253 seconds * Withoud -d:release: 10.697 seconds
Re: Estimation of π using Leibniz series
Julia compiles with `-march=native` by default so try passing `--passC:"-march=native"` to Nim. I have this in my `~/.config/nim.cfg` along with `--passC:"-flto"` (for release mode).
Re: Estimation of π using Leibniz series
It seems that Julia JIT is aware of SSE extensions and it uses them. GCC or MSVC should be emitting them too, but it depends on C code
Re: Estimation of π using Leibniz series
Thank you all. @wiffel/Nibbler, in my Julia test, I was using Pro version 0.6.1 64 bit running on Windows 10. Now, running the same .jl code on a Windows 8 64 bit (i5 CPU 650 @ 3.20GHz, 3193 Mhz, 2 Cores, 4 Processors) I got the following: 2.763225 seconds (1.77 k allocations: 95.291 KiB) Pi: 3.141592663589326 After JIT compilation: 1.863196 seconds (1.69 k allocations: 88.809 KiB) Pi: 3.141592663589326
Re: Estimation of π using Leibniz series
I compiled the same approximate version to C with gcc optimisations on, and found the execution time to be roughly comparable between Nim and C. Could Julia's JIT be doing some sort of optimisation that shortcuts the full code somehow? With the Nim version: import times, math proc leibniz(terms: int): float = var res = 0.0 for n in 0..terms: res += pow(-1.0,float(n))/(2.0*float(n)+1.0) return 4*res let t0 = cpuTime() echo(leibniz(100_000_000)) let t1 = cpuTime() echo "Elapsed time: ", $(t1 - t0) I got these output times: C:projectsNim>nim_version 3.141592663589326 Elapsed time: 6.541 C:projectsNim>nim_version 3.141592663589326 Elapsed time: 6.676 C:projectsNim>nim_version 3.141592663589326 Elapsed time: 6.594 While with the same C version: #include #include #include double leibniz(int terms) { double res = 0.0; for (int i = 0; i < terms; ++i) { res += pow(-1.0, (double)i) / (2.0 * (double)i + 1.0); } return 4*res; } int main() { clock_t start = clock(); double x = leibniz(1); printf("%.15f\n", x); printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC); } The times taken were (EDIT: used -Ofast instead and got faster times): C:projectsc>c_version 3.141592643589326 Time elapsed: 6.206000 C:projectsc>c_version 3.141592643589326 Time elapsed: 6.204000 C:projectsc>c_version 3.141592643589326 Time elapsed: 6.217000 I realise I actually got a slightly different decimal number with C, but to be honest I am not a C programmer so I am sure I did something wrong in the formatting.
Re: Estimation of π using Leibniz series
@alfrednewman I tried to replicate your test. On my computer the following (slightly modified version) of the _nim_ program and the _julia_ program have the same runtime. Whatever I do, I fail to run the _julia_ version in less than 2 seconds (as you had). Are you sure that test went OK? import times, math proc `/`(a, b: int): float = float(a) / float(b) proc leibniz(terms: int): float = for i in 0..terms: result += (-1)^i / (2*i+1) result *= 4.0 let t0 = cpuTime() pi = leibniz(100_000_000) tt = cpuTime() - t0 echo("Elapsed time: ", tt) echo("Pi: ", pi) gives >> nim c -d:release pi.nim >> time ./pi Elapsed time: 5.671875 Pi: 3.141592663589326 real0m5.706s user0m5.672s sys 0m0.000s and function leibniz(terms) res = 0.0 for i in 0:terms res += (-1.0)^i/(2.0*i+1.0) end return res * 4.0 end println("Pi: ", @time leibniz(100_000_000)) gives >> time julia pi.jl 5.770856 seconds (4.48 k allocations: 226.962 KB) Pi: 3.141592663589326 real0m6.538s user0m6.594s sys 0m0.234s
Re: Estimation of π using Leibniz series
At least so: `res += float([1,-1][n mod 2])/(2.0*float(n)+1.0)`.
Re: Estimation of π using Leibniz series
That call to `pow` to change sign may be a possible reason of slowdown.
Estimation of π using Leibniz series
Hello, How can I optimize the speed of the following proc: import times, math proc leibniz(terms: int): float = var res = 0.0 for n in 0..terms: res += pow(-1.0,float(n))/(2.0*float(n)+1.0) return 4*res let t0 = cpuTime() echo(leibniz(100_000_000)) let t1 = cpuTime() echo "Elapsed time: ", $(t1 - t0) I have the following result in my computer: 3.141592663589326 Elapsed time: 8.23 This result is almost 5x faster than my CPython counter party, but on the other hand it is around 6x slower than Julia, given the following code: function leibniz(terms) res = 0.0 for i in 0:terms res += (-1.0)^i/(2.0*i+1.0) end return res *= 4.0 end println("Pi: ", @time leibniz(100_000_000)) 1.374829 seconds (1.72 k allocations: 90.561 KiB) Pi: 3.141592663589326
Re: Nim in Action is now officially in print!
Great Job !! Mine is on the way ! All the best.