Skip to content

Instantly share code, notes, and snippets.

@chrisdone
Last active August 1, 2016 08:44
Show Gist options
  • Save chrisdone/377db99f975f23b5bac66a9c0661145b to your computer and use it in GitHub Desktop.
Save chrisdone/377db99f975f23b5bac66a9c0661145b to your computer and use it in GitHub Desktop.
pidigits: ghc vs gcc
bash-3.2$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
bash-3.2$ cat > main.c
/* The Computer Language Benchmarks Game
* http://benchmarksgame.alioth.debian.org/
*
* Contributed by Mr Ledrug
*/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
mpz_t tmp1, tmp2, acc, den, num;
typedef unsigned int ui;
ui extract_digit(ui nth) {
// joggling between tmp1 and tmp2, so GMP won't have to use temp buffers
mpz_mul_ui(tmp1, num, nth);
mpz_add(tmp2, tmp1, acc);
mpz_tdiv_q(tmp1, tmp2, den);
return mpz_get_ui(tmp1);
}
void eliminate_digit(ui d) {
mpz_submul_ui(acc, den, d);
mpz_mul_ui(acc, acc, 10);
mpz_mul_ui(num, num, 10);
}
void next_term(ui k) {
ui k2 = k * 2U + 1U;
mpz_addmul_ui(acc, num, 2U);
mpz_mul_ui(acc, acc, k2);
mpz_mul_ui(den, den, k2);
mpz_mul_ui(num, num, k);
}
int main(int argc, char **argv) {
ui d, k, i;
int n = atoi(argv[1]);
mpz_init(tmp1);
mpz_init(tmp2);
mpz_init_set_ui(acc, 0);
mpz_init_set_ui(den, 1);
mpz_init_set_ui(num, 1);
for (i = k = 0; i < n;) {
next_term(++k);
if (mpz_cmp(num, acc) > 0)
continue;
d = extract_digit(3);
if (d != extract_digit(4))
continue;
putchar('0' + d);
if (++i % 10 == 0)
printf("\t:%u\n", i);
eliminate_digit(d);
}
return 0;
}
bash-3.2$ gcc -pipe -Wall -O3 -fomit-frame-pointer -march=native main.c -o pidigits.gcc_run -lgmp
gcc -pipe -Wall -O3 -fomit-frame-pointer -march=native main.c -o pidigits.gcc_run -lgmp
bash-3.2$ time ./pidigits.gcc_run 10000 > /dev/null
time ./pidigits.gcc_run 10000 > /dev/null
real 0m2.508s
user 0m2.496s
sys 0m0.006s
bash-3.2$ /usr/local/Cellar/gcc/6.1.0/bin/gcc-6 -pipe -Wall -O3 -fomit-frame-pointer -march=native main.c -o pidigits.gcc_6 -lgmp
bash-3.2$ /usr/local/Cellar/gcc/6.1.0/bin/gcc-6 --version
gcc-6 (Homebrew gcc 6.1.0) 6.1.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
bash-3.2$ time ./pidigits.gcc_6 10000 > /dev/null
real 0m2.549s
user 0m2.535s
sys 0m0.007s
bash-3.2$ cat > Main.hs
-- The Computer Language Benchmarks Game
-- http://benchmarksgame.alioth.debian.org/
-- contributed by Bryan O'Sullivan
-- modified by Eugene Kirpichov: pidgits only generates
-- the result string instead of printing it. For some
-- reason, this gives a speedup.
import System.Environment
pidgits n = 0 % (0 # (1,0,1)) where
i%ds
| i >= n = []
| True = (concat h ++ "\t:" ++ show j ++ "\n") ++ j%t
where k = i+10; j = min n k
(h,t) | k > n = (take (n`mod`10) ds ++ replicate (k-n) " ",[])
| True = splitAt 10 ds
j # s | n>a || r+n>=d = k # t
| True = show q : k # (n*10,(a-(q*d))*10,d)
where k = j+1; t@(n,a,d)=k&s; (q,r)=(n*3+a)`divMod`d
j&(n,a,d) = (n*j,(a+n*2)*y,d*y) where y=(j*2+1)
main = putStr.pidgits.read.head =<< getArgs
-- The Computer Language Benchmarks Game
-- http://benchmarksgame.alioth.debian.org/
-- contributed by Bryan O'Sullivan
-- modified by Eugene Kirpichov: pidgits only generates
-- the result string instead of printing it. For some
-- reason, this gives a speedup.
import System.Environment
pidgits n = 0 % (0 # (1,0,1)) where
i%ds
| i >= n = []
| True = (concat h ++ "\t:" ++ show j ++ "\n") ++ j%t
where k = i+10; j = min n k
(h,t) | k > n = (take (n`mod`10) ds ++ replicate (k-n) " ",[])
| True = splitAt 10 ds
j # s | n>a || r+n>=d = k # t
| True = show q : k # (n*10,(a-(q*d))*10,d)
where k = j+1; t@(n,a,d)=k&s; (q,r)=(n*3+a)`divMod`d
j&(n,a,d) = (n*j,(a+n*2)*y,d*y) where y=(j*2+1)
main = putStr.pidgits.read.head =<< getArgs
bash-3.2$ stack ghc -- -O2 Main.hs -o pidigits.haskell
[1 of 1] Compiling Main ( Main.hs, Main.o )
Linking pidigits.haskell ...
bash-3.2$ time ./pidigits.haskell 10000 > /dev/null
real 0m1.129s
user 0m1.101s
sys 0m0.026s
bash-3.2$
bash-3.2$ stack ghc -- --version
The Glorious Glasgow Haskell Compilation System, version 7.10.3
bash-3.2$ stack ghc -- --version
The Glorious Glasgow Haskell Compilation System, version 8.0.1
bash-3.2$ touch Main.hs; stack ghc -- -O2 Main.hs -o pidigits.haskell
[1 of 1] Compiling Main ( Main.hs, Main.o )
Linking pidigits.haskell ...
bash-3.2$ time ./pidigits.haskell 10000 > /dev/null
real 0m1.155s
user 0m1.095s
sys 0m0.034s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment