That test is rigged to be a best case scenario for Go. How often do you send 1MB responses down to the client?<p>If you send 3KB responses then you would see both setups are much closer in performance.<p>Factor in some actual I/O and the difference will be even less. Then you'll eventually realize using either one makes little difference when it comes to performance.<p>This is why micro benchmarks are pure jokes. A real world site has a mix of response sizes, database I/O and caching. It's the only way to test something properly and you'll see if you properly test both there will be little difference in performance.
If you read the original blog post on <a href="http://blog.safariflow.com/2013/02/22/go-as-an-alternative-to-node-js-for-very-fast-servers/" rel="nofollow">http://blog.safariflow.com/2013/02/22/go-as-an-alternative-t...</a>, one of the commentators actually attempted the comparison between node.js and go, and his results for node.js was significantly faster.
Is it possible to write Go in a functional way? Are there first class functions? Anonymous functions? If so it seems it would be possible to write highly functional code given the flexibility of interface{}
Here is the original link:
<a href="http://blog.safariflow.com/2013/02/22/go-as-an-alternative-to-node-js-for-very-fast-servers/" rel="nofollow">http://blog.safariflow.com/2013/02/22/go-as-an-alternative-t...</a>
I did the benchmarks outlined at the end of the article.<p>Summary of results:<p>1. Node.js v0.10.15, single worker: 46.2 seconds<p>2. Node.js v0.10.15, cluster 8 workers using naught: 17.2 seconds<p>3. Go 1.0.2, GOMAXPROCS left default: 3.5 seconds<p>4. Go 1.0.2, GOMAXPROCS=8: 3.7 seconds<p>Detailed results below:<p>1. Node.js v0.10.15, single worker<p><pre><code> Concurrency Level: 100
Time taken for tests: 46.217 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 10486510000 bytes
HTML transferred: 10485760000 bytes
Requests per second: 216.37 [#/sec] (mean)
Time per request: 462.168 [ms] (mean)
Time per request: 4.622 [ms] (mean, across all concurrent requests)
Transfer rate: 221580.08 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 3
Processing: 193 461 36.2 450 944
Waiting: 16 235 127.3 235 534
Total: 193 461 36.2 450 944
Percentage of the requests served within a certain time (ms)
50% 450
66% 467
75% 470
80% 486
90% 492
95% 514
98% 517
99% 545
100% 944 (longest request)
</code></pre>
2. Node.js v0.10.15, cluster 8 workers using naught<p><pre><code> Concurrency Level: 100
Time taken for tests: 17.199 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 10486510000 bytes
HTML transferred: 10485760000 bytes
Requests per second: 581.41 [#/sec] (mean)
Time per request: 171.995 [ms] (mean)
Time per request: 1.720 [ms] (mean, across all concurrent requests)
Transfer rate: 595408.80 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 3
Processing: 7 171 116.4 149 739
Waiting: 5 96 81.9 71 710
Total: 8 171 116.5 150 740
Percentage of the requests served within a certain time (ms)
50% 150
66% 197
75% 236
80% 266
90% 324
95% 397
98% 438
99% 493
100% 740 (longest request)
</code></pre>
3. Go 1.0.2, GOMAXPROCS left default<p><pre><code> Concurrency Level: 100
Time taken for tests: 3.542 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 10486730000 bytes
HTML transferred: 10485760000 bytes
Requests per second: 2823.16 [#/sec] (mean)
Time per request: 35.421 [ms] (mean)
Time per request: 0.354 [ms] (mean, across all concurrent requests)
Transfer rate: 2891181.71 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 0.3 1 3
Processing: 9 35 2.2 34 56
Waiting: 0 1 1.3 1 22
Total: 12 35 2.3 35 57
Percentage of the requests served within a certain time (ms)
50% 35
66% 36
75% 36
80% 36
90% 37
95% 38
98% 39
99% 41
100% 57 (longest request)
</code></pre>
4. Go 1.0.2, GOMAXPROCS=8<p><pre><code> Concurrency Level: 100
Time taken for tests: 3.657 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 10486730000 bytes
HTML transferred: 10485760000 bytes
Requests per second: 2734.54 [#/sec] (mean)
Time per request: 36.569 [ms] (mean)
Time per request: 0.366 [ms] (mean, across all concurrent requests)
Transfer rate: 2800429.67 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 0.4 1 3
Processing: 19 36 2.5 35 57
Waiting: 0 1 1.1 1 16
Total: 20 37 2.5 36 58
Percentage of the requests served within a certain time (ms)
50% 36
66% 37
75% 37
80% 37
90% 38
95% 39
98% 42
99% 51
100% 58 (longest request)</code></pre>
Did you compare with a JVM toolkit with similar concurrency libraries like Akka/Scala?<p>Am curious to find out the results. There was a recent, don't remember which, comparison that put Scala way ahead of Go possibly because of a superior GC.<p>Wonder if the results correlate
I've worked with both node and Go. There is a lot of hyperbole and fluff points about Go's strengths in the original article (sorry to the author!). Things that are touted as huge wins for Go have equally better things in node. Both platforms are great and they both have appeal for different people.<p>My eloquent post was eaten by an expired link on the original article but here are some counter-points:<p>The commutative property applies to all code that has semicolons to end lines. Use jslint/jshint/an IDE. The symbol is "optional" not marked as "leave it out because it makes scripts nicer."<p>Use jslint/jshint/an IDE to prevent globals. Seriously. It's the same as running go fmt on your code.<p>Forcing people to use "channels" as a best practice to accomplish scaling is the same as the best practice of callbacks - but yes, channels are nicer to use. Node standard modules require callbacks by default as Go standard library implements channels by default.<p>32-bit integers in JS don't have float problems because the precision doesn't break<p>Typing in Go can still be annoying for some situations. If you're dealing with external content (creating an API with mutable content that you still need to read) it can be annoying at best (e.g. reminds me of writing C). Types in Go are a nice implementation though.<p>npm is way better than go get and there are at least 3 projects in Go trying to replicate npm's ease-of-use<p>The vim/emacs syntax highlighter is nice but it's awfully frustrating if you don't use vim/emacs. This is due to Go's young age, but you shouldn't be forced into using a certain editor to get syntax highlighting.<p>The alternative to "go fmt" for Javascript is a good IDE or jslint/jshint.<p>In Go, you get a lot in the standard library, but you miss out on a lot in the community. Yet another young language problem, you wind up having to roll your own for a lot of things that should just exist. It can be frustrating looking for answers because you might be the first person working on the problem in the language.<p>Also, just as a general thing I've perceived, people seem to argue static types vs dynamic types more than that a particular language is "better." Go and JS/node are both great!!!! Go is typed, JS is not and you deal with the consequences in both situations. Static typed languages have big faults with external data handling that sometimes cripple features (or makes them far more difficult to accomplish). Dynamic typed languages can fall victim to variables being used incorrectly (especially when not using an IDE). That's the biggest bulk of the difference in my experience.
So beyond the ironic comment mentioned before with the Golang Hello world tutorial using Chinese, what is the real reason behind the Chinese following behind Go?<p>It seems like this site confirm there must be a pretty dedicated Golang following, but I cannot figure out for the life of me why. Does anyone actually know?
I know this post is about speed, but you should always remember that with node.js you only need JS developers while with Go you are probably going to need both Go and JS (for front-end stuff) developers.<p>Just my two cents.
Are these trivial micro benchmarks, (simply respond with an empty 200) not totally misleading to focus on?
Especially when you start to factor in many real workloads that involve disk or network io.