montecarlo pi estimations in various languages. Just a bit of fun.
Requires:
- rustc
- go
- gcc
- python2
- pypy
- python3
- ruby
all: monte-c monte-go monte-rs monte-gccgo | |
monte-go: | |
go build montepi.go && mv montepi monte-go | |
monte-rs: | |
rustc -O -o monte-rs montepi.rs | |
monte-c: | |
gcc -std=c99 -O2 -o monte-c montepi.c -lm | |
gcc -std=c99 -o monte-c-unop montepi.c -lm | |
monte-gccgo: | |
gccgo -g -O2 -c montepi.go | |
gccgo -g -O2 -o monte-gccgo montepi.o | |
rm -f montepi.o | |
gccgo -g -c montepi.go | |
gccgo -g -o monte-gccgo-unop montepi.o | |
rm -f montepi.o | |
clean: | |
rm -f monte-c monte-go monte-rs monte-gccgo monte-gccgo-unop monte-c-unop | |
fast: all | |
@gcc --version 2>/dev/null |grep -E "(gcc|LLVM)" | |
/usr/bin/time -p ./monte-c | |
@echo "" | |
@go version | |
/usr/bin/time -p ./monte-go | |
@echo "" | |
@echo gccgo --version |grep "gcc" | |
/usr/bin/time -p ./monte-gccgo | |
@echo "" | |
@echo gccgo --version |grep "gcc" | |
/usr/bin/time -p ./monte-gccgo-unop | |
@echo "" | |
@rustc --version | |
/usr/bin/time -p ./monte-rs | |
slow: fast | |
@echo "" | |
@ruby --version | |
/usr/bin/time -p ./montepi.rb | |
@echo "" | |
@python -V | |
/usr/bin/time -p ./montepi.py | |
@echo "" | |
@pypy -V | |
/usr/bin/time -p pypy ./montepi.py | |
@echo "" | |
@python3 -V | |
/usr/bin/time -p python3 ./montepi.py | |
@echo "" | |
@php --version |grep cli | |
/usr/bin/time -p php ./montepi.php | |
/* montecarlo approximation of pi in c */ | |
#include <stdio.h> | |
#include <time.h> | |
#include <stdlib.h> | |
#include <math.h> | |
#define ITERATIONS 100000000 | |
int in_circle(float x, float y) { | |
if (sqrt(x*x + y*y) <= 1.0) { | |
return 1; | |
} | |
return 0; | |
} | |
int main() { | |
srand(time(NULL)); | |
rand(); | |
int hits=0; | |
for (int i=0; i<ITERATIONS; i++) { | |
float r1 = (float)rand()/(float)RAND_MAX; | |
float r2 = (float)rand()/(float)RAND_MAX; | |
if (in_circle(r1, r2)) { | |
hits++; | |
} | |
} | |
printf("Pi: %0.6f\n", (4 * ((float)hits / ITERATIONS))); | |
return 0; | |
} |
// montecarlo approximation of pi in go | |
package main | |
import ( | |
"math" | |
"math/rand" | |
"time" | |
) | |
const iterations = 100000000 | |
func inCircle(x, y float64) bool { | |
return math.Sqrt(x*x+y*y) <= 1.0 | |
} | |
func main() { | |
source := rand.NewSource(time.Now().Unix()) | |
r := rand.New(source) | |
var h int | |
for i := 0; i <= iterations; i++ { | |
if inCircle(r.Float64(), r.Float64()) { | |
h++ | |
} | |
} | |
pi := 4 * float64(h) / float64(iterations) | |
println("Pi:", pi) | |
} |
<?php | |
$iterations = isset($argv[1]) ? (int) $argv[1] : 100000000; | |
$randmax = mt_getrandmax(); | |
$hits = 0; | |
function inCircle($x, $y) { | |
return sqrt($x * $x + $y * $y) <= 1.0; | |
} | |
for ($i = 0; $i < $iterations; ++$i) { | |
$x = mt_rand() / $randmax; | |
$y = mt_rand() / $randmax; | |
if (inCircle($x, $y)) { | |
++$hits; | |
} | |
} | |
printf("Pi: %0.6f\n", (4 * ($hits / $iterations))); |
#!/usr/bin/env python | |
from time import time | |
from random import random, seed | |
from math import sqrt | |
seed(time()) | |
iterations = 100000000 | |
if 'xrange' not in dir(__builtins__): | |
__builtins__.xrange = range | |
def in_circle(x, y): | |
return sqrt(x*x + y*y) <= 1.0 | |
hits = 0 | |
for i in xrange(1, iterations): | |
if in_circle(random(), random()): | |
hits += 1 | |
pi = 4 * (hits / float(iterations)) | |
print("pi = %0.6f" % (pi)) |
#!/usr/bin/env ruby | |
def in_circle(x, y) | |
return Math.hypot(x, y) <= 1.0 | |
end | |
iterations = 100000000 | |
h = 0 | |
(0..iterations).each do |i| | |
if in_circle(rand(), rand()) | |
h+=1 | |
end | |
end | |
pi = 4.0 * h / iterations.to_f | |
puts "Pi: #{pi}" |
// montecarlo approximation of pi in rust | |
use std::rand; | |
use std::rand::{Rng, XorShiftRng}; | |
fn in_circle(x :f64, y :f64) -> bool { | |
let f = (x*x + y*y).sqrt(); | |
f <= 1.0 | |
} | |
fn main() { | |
let iterations = 100000000i; | |
let mut rng: XorShiftRng = rand::random(); | |
let mut hits = 0i; | |
for _ in range(0i, iterations) { | |
let x = rng.gen::<f64>(); | |
let y = rng.gen::<f64>(); | |
if in_circle(x, y) { | |
hits+=1; | |
} | |
} | |
let pi :f64 = 4.0 * hits as f64 / iterations as f64; | |
println!("Pi: {}", pi); | |
} |
I didn't realize this gist had comments ^_^;
Once you get down to it, these are mostly about the rngs; especially the fastest ones. It's by far the most expensive part of the computation once you've got rid of all the dumb stuff.
Also, luajit, v8 and pypy are pretty incredible pieces of software.