Can someone explain this observation of this Go vs Node PoC I'm working on?

blov · · 503 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I&#39;ve been building a reverse proxy proof of concept for a routing tier for work but I&#39;m not using the native http reverseproxy because I need to make a call to multiple services based on config. </p> <p>So it&#39;ll make a call to this service, localise it maybe and redirect it to itself if needed, then make a GET call to an external service depending on the URL then return the original payload.</p> <p>So I&#39;ve got a Chi server with regex routes then I&#39;m making a http.Get then rendering the response body.</p> <p>First off would this have performance implications compared to using the ReverseProxy native package?</p> <p>Secondly I&#39;m doing some load testing against a Go app that just spits back a static asset. I&#39;ve also got a Node.js PoC which does the exact same thing but I&#39;m seeing that Go is only pushing 10% more Req/s and a slightly faster latency. However I&#39;m seeing that Go is using more CPU to do slightly more. </p> <p>Specifically I&#39;m running the following command to load test using the <code>wrk</code> tool.</p> <p><code>wrk -d 300 -c 50 http://URL</code></p> <p>Go is giving me about 150 req/s more than Node but it&#39;s using double the CPU to do it.</p> <p>Is this something to do with the implementation? With the way Go works compared to Node&#39;s event loop handing the job down to the kernal often?</p> <hr/>**评论:**<br/><br/>qu33ksilver: <pre><p>I didn&#39;t get why you couldn&#39;t use reverseproxy because you had to make multiple calls based on config. Perhaps you can clarify ?</p></pre>bustyLaserCannon: <pre><p>Honestly I can&#39;t remember that well, I made the PoC a few months ago but I remember not being able to get it to work. </p> <p>Maybe it was because of the regex requirement in the URL parsing? It meant I couldn&#39;t use the standard http/server</p></pre>epiris: <pre><p>You need to post the code for a helpful response, I’ve never seen a correct benchmark between node and Go that Go doesn’t come out ahead on by a large margin. </p></pre>jerf: <pre><p>IIRC, for the Node server, you&#39;re basically running through almost 100% C code for the server. It&#39;s not a test of &#34;Node&#34; but a test of their C-based webserver code. Go being ~2x slower than C is about right.</p> <p>As is often the case, it&#39;s difficult to write a simple benchmark that means anything, because anything simple enough for you to write as a benchmarking case is simple enough to have been heavily optimized and not a valid benchmark of the speed you can expect in your code.</p> <p>In this case, while Go is broadly speaking substantially faster than Node on real code, it is very likely that you&#39;re going to have that time dominated by the work the respective webservers are going to do, as you receive substantial requests and likely do just a smidge of work to figure out what to do with them, then the webservers take over again. I wouldn&#39;t pick Go over Node for &#34;performance&#34; in this case. I would be looking at which work better. In Go&#39;s case, as soon as you do anything that involves some sort of operation that in the node world would be considered &#34;blocking&#34;, you start to see significant code simplicity advantages for Go because in Go, you just write the code.</p> <p>I myself have a relatively thin Go-based webserver that mostly proxies stuff through, but first has to hit a couple of APIs on other webservers to decide what to do. The Go code that does that is simpler than anything Node could do, because even simply having to slather your code with <code>async</code> and <code>await</code> is already more complicated than Go. I just have handlers that run a request out to those other servers and write straightforward code to handle it. In practice, dozens or even hundreds of these requests may be pipelined up at a time, and I&#39;m not sitting here directing them around, it just works.</p> <p>Edit: If there&#39;s anything about karma-based systems that piss me off, it is when objective facts get downvoted. Go is slower than C. Node is slower than Go on general programming tasks, despite all of its JIT work. Node&#39;s web server is, as far as I know, almost entirely written in C, which is done precisely because Node in general is much slower than C and so there was no way the Node team could write a webserver in pure Node and be performance-competitive with other web servers. If they could, they certainly would have. I&#39;m not saying these things because of a rah-rah team thing in either direction; I&#39;m saying them because I am a professional engineer, and that means I need to have a correct and precise understanding of the characteristics of my tools. Pushing downvote buttons on a website will not suddenly make your Node code run at C speeds.</p> <p>(For one thing, speed isn&#39;t everything. Go is noticeably slower than C, but I use it a ton, because there&#39;s a lot more to the utility of a language than its raw speed, even though that&#39;s a very important element. But, ultimately, it is absolutely undeniable that we pay a runtime cost for Go&#39;s compilation speed, which is obtained through the lack of the sort of fancy optimizations that C and C++ compilers implement. Again, this is not a &#34;rah rah go my team!&#34; sort of thing. It is an objective fact that you need to understand about your tools.)</p></pre>bustyLaserCannon: <pre><p>That&#39;s a good point, might be what you mentioned in your first paragraph.</p> <p>I like what you said about what work it has to do.. maybe Node would work better due to the lack of work it really needs to do.</p></pre>jerf: <pre><p>If you&#39;re already familiar with Node, I would consider it the best choice locally, unless you&#39;re looking for a reason to learn Go, in which case this sounds like a pretty sensible learning project.</p> <p>Long-term, and speaking personally, I definitely prefer Go because I&#39;ve been programming in things that work like Go for longer than Node has been around (Erlang and Haskell, which are esoteric in various other ways, but also both have the casual &#34;need a thread? just use one&#34;), and the idea of having to go back to even having to worry about <code>async</code> and <code>await</code>, let alone all the other ways of dealing with the problem, is just not something I&#39;m willing to entertain after so many years of using things that just do it right. I think you&#39;re better off in languages where that is all just handled by the compiler or runtime, and using your limited cognitive firepower on the actually important problems, but that&#39;s just me.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

503 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传