Go vs Node vs Rust vs Swift
Some days ago ago Apple released Swift as open source language with instructions for Ubuntu Linux 15.10. So I decided to do a couple of simple benchmarks just to test some basic general purpose things like cpu, functions, read/write and not sequential access to arrays, concurrent parallel execution where possibile.
UPDATE: Here is the source code, somebody asked for it, all the tests look almost the same in all languages. I've also add gccgo as compiler with "-O" optimization
Bench1
It generates 2 growable arrays with incremented numbers, then it returns the sum of some of their elements.
Fib
Unoptimized Fibonacci sequence, a recursive function.
Why this comparison?
Because 3 programming languages are:
- Modern user-friendly typed languages
- The syntax is very similar (at least for basic scenarios)
- To see if the performance benefits are worth and evident or not
Test environment
CPU: Intel Core 2 Duo E8400 @3.00Ghz
OS: Ubuntu 15.10, Kernel Linux 4.2.0-19-generic
- Golang: go version go1.5.2 linux/amd64,gccgo (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010
- NodeJS: Node v5.1.1
- Swiftlang: Swift version 2.2-dev
- Rustlang: rustc 1.5.0-beta.5 (b716bc93c 2015-12-02)
Performance
In all test is measured the total execution time with the time
command. In NodeJS / Javascript the value is compilation+execution, all tests are run 3 times and the medium result is taken and rounded.
In the first test the winner is Rust, both Rust and Swift get a noticeable boost if the binary is compiled with "-O" flag.
Here the fastest is Swift, then Rust. It is a bit weird because they both compile in LLVM.
Syntax
All these new user-friendly typed languages have a very similar syntax. In Rust you have much more control in your code and some conversions aren't done automatically, I had to specify i as usize
to use that integer as index.
In Go you have a specific operator <-
to deal with channels.
Concurrency / Parallelism
I tried to run another benchmark, the sum of fib(45) + fib(43).
- Golang: to enable all the cores, you have to put in your code
runtime.GOMAXPROCS(num of cores you want to use)
- Rust: there are several ways for different use cases, I used the 3rd part lib async-await, the result is correct
but it seems the computation on one core slow down even if the task isn't finished yet. Upgrading from beta to Rust 1.5 stable I no longer have this issue. - NodeJS: it is single thread, you can use all your cores running multiple instances of your code.
- Swift: It should be possible to use libdispatch on Linux but I didn't tried it
Use cases and opinions
General use case: choose the one you like more, it is mostly a syntax and ecosystem issue.
Go: mature, concurrency, backend, micro services, CLI utilities
Node: mature, possible code sharing with frontend, it's JavaScript, functional features
Rust: low level control, safety, concurrency, speed, functional features
Swift: IOS native & OSX built-in, functional features
I didn't compare these languages to dynamic languages like ruby or python because there are already a lot of comparisons with them.
Personally I like JavaScript and its ES2015, ES2016 and I don't have a preferred typed language.
What's your choice? And for what? You can comment on HN or on Reddit.