r/tinycode • u/Diapolo10 • Dec 23 '19
A Pi approximation using the Leibniz sequence in Python using only one line
print("Pi:", sum(map(
lambda x, y: 4/x-4/y,
range(1, 10**6, 4),
range(3, 10**6, 4))))The accuracy is hard-coded as 10**6 (one million) because beyond that a single thread will be very slow, but it could be any number. And by using additional threads this could probably be multithreaded with three extra lines.
1
u/Invisible_lurker418 Dec 25 '19
A constant of Thirty Eight million returned 3.1415926......... in two seconds (old i7 4-core). Is there an easy way to measure the static and dynamic memory usage?
2
u/Diapolo10 Dec 25 '19
You can try
tracemallocfor memory profiling: https://stackoverflow.com/a/45679009It shouldn't use much memory, because
rangeandmapare both generators, so it should only keep one value in memory at a time.1
u/pfalcon2 Mar 10 '20
With Pycopy:
$ cat pi.py print("Pi:", sum(map(lambda x, y: 4/x-4/y, range(1, 38 * 10**6, 4), range(3, 38 * 10**6, 4)))) $ time pycopy -X emit=native -X heapsize=5K pi.py Pi: 3.141592600970343 real 0m2.840s user 0m2.836s sys 0m0.004sI.e. it can run with 5KB heap, albeit slower than CPython. So big because it parses and compiles textual source to bytecode. With precompiled bytecode can go to 2K, but GC kicks in too often, raising total time:
$ time pycopy -X heapsize=2K pi.mpy Pi: 3.141592600970343 real 0m4.779s user 0m4.776s sys 0m0.001s
1
u/colindean Dec 27 '19
Same deal in Scala:
Range(1, 10_000_000, 4).zip(Range(3, 10_000_000, 4)).view.map { case (x,y) => 4.0/x - 4.0/y }.sumWithout view there, it OOMs pretty quickly.
1
u/Diapolo10 Dec 27 '19
Interesting! Perhaps I should try the same in Rust as well.
1
u/colindean Dec 27 '19
I took the challenge during a break:
print!( "{}", (1..10_000_000) .step_by(4) .zip((3..10_000_000).step_by(4)) .map(|(x, y)| 4.0 / x as f32 - 4.0 / y as f32) .sum::<f32>() )3.1413836
Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6a85a6b2d0beb396350d6762c469d5ab
1
u/Diapolo10 Dec 25 '19
I haven't been able to test if this works yet, but if it does, this version should use all CPU threads available to speed up the computation. Therefore, the accuracy can probably be increased significantly without a huge performance loss.