Last active
October 26, 2016 15:22
-
-
Save kabutz/b7f724333d0e4868c48763d65ec3e507 to your computer and use it in GitHub Desktop.
A simple exponential time shootout between C, Java and Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Algorithm is exponential - very bad. It is just meant to exercise the CPU a bit and | |
to see what happens with different languages. Not representative of real code. | |
Interesting that Java beats C, thanks to HotSpot. I expected Swift to be as fast as C | |
at least. I also expected the compiled Swift to be faster than when run as a script. | |
A bit disappointed, but more time needed to see where the bottlenecks are. Plus I | |
need to run some real code for benchmarking. | |
Update: swiftc -O improved the speed quite a bit to be about the same speed as Java | |
Disclaimer: Whilst I know Java pretty well, the last time I wrote a C program was | |
probably in 1992. I couldn't even remember how to printf() a long! And I also | |
don't know Swift very well yet. I'm hoping that someone can show me what I'm doing | |
wrong that the compiled Swift code runs slower than swift < fib.swift. | |
Disclaimer2: Yes, I know we should run the code several times to get an average speed, etc. :-) | |
Times on my machine MacBook Pro (Retina, 15-inch, Late 2013), 2.6 GHz Intel Core i7 | |
Java - user 0m7.981s | |
Swift 3.0 compiled with -O - user 0m8.303s | |
C with -O - user 0m10.437s | |
C - user 0m12.649s | |
Swift 3.0 uncompiled - user 0m14.170s | |
Swift 3.0 compiled - user 0m22.140s | |
*/ | |
/* Java */ | |
public class Fib { | |
public static void main(String... args) { | |
for(int n=10; n <= 44; n++) { | |
System.out.printf("fib(%d)=%d%n", n, fib(n)); | |
} | |
} | |
public static long fib(int n) { | |
if (n < 2) return n; | |
return fib(n-1) + fib(n-2); | |
} | |
} | |
/* C */ | |
#include<stdio.h> | |
unsigned long fib(int n) { | |
if (n < 2) return n; | |
return fib(n-1) + fib(n-2); | |
} | |
int main() { | |
for(int n=10; n <= 44; n++) { | |
printf("fib(%d)=%lu\n", n, fib(n)); | |
} | |
} | |
/* Swift 3.0 */ | |
func fib(_ n : Int) -> Int { | |
if n < 2 { | |
return n | |
} else { | |
return fib(n-1) + fib(n-2) | |
} | |
} | |
for n in 10...44 { | |
print("fib(\(n))=\(fib(n))") | |
} |
Any volunteers for an APL version, which usually runs an order of magnitude faster?
And if you have a few mSecs to spend, impress your boss with:
Clear["Global`fib"];
phi := (1 + Sqrt[5])/2;
fib[n_] := fib[n] = Simplify[(phi^n - (1 - phi)^n) /Sqrt[5]];
Timing[Table[{n, fib[n]}, {n, 1, 44}]]
but gcc -O3 makes the C version 25% faster than the Java version on my machine. Linux with everything updated Intel(R) Core(TM) i7-3960X CPU @ 3.30GHz.
-O3 seems fair since you allow hotspot to do all sorts of magic... ;)
What if the Java test uses boxed types (to take it closer to Swift)?
What if you ran the Java one using -server?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
And I took the extra burden computing fib[1]...fib[9]!