Node.JS - supposed to be faster, BUT HOW!?



  • Continuing the discussion from WTF am I doing with Node and The Intern?:

    @ben_lubar said:

    I can't imagine a nodejs server being terribly efficient if it can only access one CPU core and every request has to wait in line for the previous n - 1 requests.

    Yeah that's pretty much the whole giant "WTF"-ism I've been getting from Node.js since day 1.

    Nobody's sufficiently explained to me how Node's callback model is better than the plain ol' threadpools we've been using for decades.



  • Well, it means you can run the same code on the client as on the server.

    :trolleybus:


  • Grade A Premium Asshole

    @ben_lubar said:

    Well, it means you can run the same code on the client as on the server.

    That might speed development time, but it does fuck-all for concurrency or speed on the processor. When people talk about Node.JS they seem to just throw around a ton of buzzwords. None of them seem to make any real sense.



  • This argument never made any sense to me. Client code does client stuff. Server code does server stuff. I don't even know if you can actually get Node base libraries on the client, or DOM on the server, but I don't even care, because WHY WOULD YOU DO THAT.

    I think the only reason behind Node is to accommodate the shitty programmers who never learned anything but JS, and now everything's a nail to them.



  • @Polygeekery said:

    That might speed development time, but it does fuck-all for concurrency or speed on the processor. When people talk about Node.JS they seem to just throw around a ton of buzzwords. None of them seem to make any real sense.

    Right I'm with you. Maybe if Node..net (that's node dot dotNet, get it? Clever) existed (and don't tell me that it does because I don't want to hear it), but even then how could it be faster than asp.net?

    And it's not just, "I don't see how this is faster", it's closer to, "I don't see how this could possibly ever be faster, even in a magical land of elves and fairies".

    Honestly, I believe any speed increase is attributable to:

    1. Lazy developers who don't bother actually testing their performance
    2. An environment that has fewer features, therefore does less work, therefore performs slightly better if you don't need those features

    Lemme tell you, I spent a lot of time doing callback/event-based programming on Classic MacOS and that wasn't an environment known for data processing speed.


  • Grade A Premium Asshole

    @blakeyrat said:

    node dot dotNet, get it?

    Yep, got it.

    @blakeyrat said:

    Clever

    Not really.

    @blakeyrat said:

    And it's not just, "I don't see how this is faster", it's closer to, "I don't see how this could possibly ever be faster, even in a magical land of elves and fairies".

    Yeah, and not to mention that any server with over two processors is going to have the rest of them just sitting there idle and not doing shit.

    Node.JS makes no fucking sense to me. Why is that a thing?

    @blakeyrat said:

    Lemme tell you, I spent a lot of time doing callback/event-based programming on Classic MacOS and that wasn't an environment known for data processing speed.

    Classic Mac is to you, what DF is to @ben_lubar


  • Winner of the 2016 Presidential Election

    Wait, are you seriously supposed to call that thing node-dot-js?

    If all the other things weren't enough that just convinced me never to use it.



  • I can do multithreaded bullshit in browser JavaScript. Example: https://benlubar.github.io/cmvjs/#https://static.logical.so/df-ai-1423662407.cmv



  • Node.js forces you to write io-bound code in a certain way. Where all io operations are handled through their own lightweight thread pools, and user code is all synchronous. It turns out cpu is blazing fast compared to hdd and network, so even though you can't parallelize cpu code, the gains you get for just having lighter weight threads (thus able to start more of them) makes up for it.

    I don't think there's anything stopping you from writing node-like code in C#. It'd just take a lot of work to set up systems node gives you bundled in.

    In fact, I'd be interested to see someone try just that.



  • Node.js is fast for a single-threaded process. I still only see it as viable for hobbyist-type projects but it works very well for that once you come to grips with callback hell. Also great for web projects because many of the libraries you can get via npm work exactly the same on both client and server.


  • sockdevs

    @cartman82 said:

    I don't think there's anything stopping you from writing node-like code in C#. It'd just takes a lot of work to set up systems node gives you bundled in.

    Not since they added async and await to the language; now, if anything, it's easier to write Node-like code in C# than in Node.js, because the compiler does the transformation to CPS for you ;)



  • Not sure if that works the same way behind the scenes.


  • sockdevs

    Probably not, but I do know they did a lot of work to get those features working.



  • If you mean development, it's better than PHP because it's the same language as the FE and easier to deploy than JEE/.Net

    About CPU, well, it's async so you're not bound by I/O and yes, you can do that also in JEE/.Net with actors and the like, but it feels weird for OO languages. Also, good multitasking, in JEE at least, is hard and not every developer out there knows how to implement it properly.

    Anyway, we have some projects which kind of depend on very simple backend code that (as you can see in another post I can't link to from mobile) use PHP and that I will be moving to Node for newer projects. Basically because you streamline the whole process from a single environment:

    • code
    • dependencies
    • packaging

    I don't like JS and I don't like Node, but hell it makes working with JS web apps very easy



  • @ben_lubar said:

    I can do multithreaded bullshit in browser JavaScript.

    WebWorkers are brand spanking new, since I did JS 8 hours a day at least.


  • sockdevs

    @blakeyrat said:

    Nobody's sufficiently explained to me how Node's callback model is better than the plain ol' threadpools we've been using for decades.

    inherantly superior? not necessarily, but it does have several advantages because of language choices:

    • All IO is async, always.
      • This makes you write async IO bound so you can't block the CPU waiting for IO
    • The threading pool is baked into the callback model
    • as a programmer you don't have to pay any special attention to the threading. let the language handle it for you.

    Those are the two biggest ones.

    I still don't buy the argument that it avoids context switching between serverside and client side languages. On any project of sufficient side you are going to have developers that work on UI and developers that work on back end. that advantage feels like a red herring to me... still it is often cited so i guess i can include it.

    it is possible to make C# as efficient as NodeJS, but it requires extra effort and because the language falls easier into synchronous models you end up blocking CPU for IO unless you are extremely rigorous. Node JS sets you up for success in async programming and C# just gives you the tools.



  • Why is that better than having the ability to have multiple threads and not block all threads when an IO operation is waiting?


  • sockdevs

    I believe the intention is to make multithreading automatic; the developer doesn't have to figure out whether to create a thread or not, nor do they have to concern themselves with its lifetime.
    C#'s async/await model is pretty similar; the compiler/runtime sorts out the threading, so the dev doesn't have to.

    That's not to say the C# implementation always creates a thread; if the async operation completes soon enough (or the CPU is idle enough), it'll execute on the current thread. I would imagine Node.js is similar in that respect.


  • mod

    "It must be fast, Netflix uses it."

    That's all I hear >.>



  • Except that's not quite true; node.js can use multiple cores, but it must be explicitly programmed. Why this is true by design is probably a larger question. For instance: http://blog.carbonfive.com/2014/02/28/taking-advantage-of-multi-processor-environments-in-node-js/


  • sockdevs

    Best answer i have for that is: because it avoids context switching on the processor. because everything is in the same program space the processor never has to flush pipeline and switch to another thread. this prevents any thread switch lag.

    Of course that argument only gives you an advantage at high CPU loads, for lower CPU loads either way works with negligable difference so if the language is going to do that for you it might as well go for the high CPU situation.



  • @ben_lubar said:

    Well, it means you can run the same code on the client as on the server.

    This is a niche feature, really, but it can be quite useful. In particular, it is very useful for code that checks data types and consistency. Some newer (I would say gimmicky) frameworks use it to allow rendering to take place selectively on the server or client according to load or various other things. A neat trick... whether it's actually useful I suppose only time and the number of bugs it unintentionally generates will tell.



  • Oh sweet Lord Microsoft, I just realized I posted a blog containing coffeescript... I must now go flog myself by trying to refactor some VBA macros as penance.



  • @VaelynPhi said:

    This is a niche feature, really, but it can be quite useful. In particular, it is very useful for code that checks data types and consistency

    The one case where I've found it useful is with websockets and data serialization. There is no doubt that the object I send over the socket from the server will be the exact same layout with the same fields, datatypes, and formats when it pops out on the client end of the socket.

    I've done WCF web services in the past and there are always strange edge-cases when consuming them from, say, JavaScript or Objective-C clients.



  • @cartman82 said:

    I don't think there's anything stopping you from writing node-like code in C#.

    It would be trivial, C# already has all of the foundational code required. It's just a matter of, "why the fuck WOULD you?"



  • @cartman82 said:

    Not sure if that works the same way behind the scenes.

    If it doesn't, it probably works better. Not worse.

    ... actually the functionality is rough in a few places. For example, it has troubles with try/catch exception handling. And you can't use it with "lock()"-- although that kind of goes into the "duh" category, remember people will be porting older code to this model, and the older code may well use lock() and it sucks that it doesn't work right.

    @accalia said:

    as a programmer you don't have to pay any special attention to the threading. let the language handle it for you.

    As opposed to ASP.NET where you-- oh wait. I don't know threading in Java, but as a C# developer I see this as a solved problem for many, many years.

    @accalia said:

    it is possible to make C# as efficient as NodeJS, but it requires extra effort and because the language falls easier into synchronous models you end up blocking CPU for IO unless you are extremely rigorous.

    I could kind of see that argument-- it's not that C# does it worse, it's that C# still has the option of "doing it wrong". (Assuming you agree that blocking on I/O is wrong, which in the case of smart threading with thread hopping like ASP.NET is in no way clear.)

    @RaceProUK said:

    I believe the intention is to make multithreading automatic; the developer doesn't have to figure out whether to create a thread or not, nor do they have to concern themselves with its lifetime.

    You don't have to do any of that in the ASP.NET model, either, though. In fact, the ASP.NET model works better if you never explicitly create a thread and just ignore the entire concept of "threads" in your particular application. (You can explicitly create threads, but those threads can't be thread-hopped and they have the potential of being unexpectedly killed if the AppPool recycles while the thread is running.)


  • sockdevs

    @blakeyrat said:

    Assuming you agree that blocking on I/O is wrong

    there is not much we agree on, but this this we have an accord on.

    blocking IO is wrong.


  • sockdevs

    @blakeyrat said:

    You don't have to do any of that in the ASP.NET model, either, though.

    True, but that's no help if you're working in anything that isn't ASP.NET, like WPF; that's when async/await comes in. In fact, IIRC, the WinRT runtime API defaults all potentially blocking ops to async, including I/O.



  • @accalia said:

    blocking IO is wrong.

    Ugh SO links.

    I can't find a good explanation, but basically thread agility is magic. Alas, if you search for it, all you get is bug reports that it screws up [ThreadLocal] variables in legacy code.



  • @Polygeekery said:

    That might speed development time, but it does fuck-all for concurrency or speed on the processor.

    If that significantly speeds up your development, you need better developers. Mastering multiple languages is not the hard part of this job.



  • @ben_lubar said:

    Why is that better than having the ability to have multiple threads and not block all threads when an IO operation is waiting?

    Because when each request occupies a thread until it's completed, you either end up with unbounded number of threads, or your thread pool ends up being full and the CPU is still idle because all threads are blocked by requests waiting for external resources.

    Also, in a callback model additional CPU-bound work for the same request may be scheduled while waiting for I/O to complete. In a blocking I/O model you'd need multiple threads per request to accomplish that.


  • Winner of the 2016 Presidential Election

    @ben_lubar said:

    Well, it means you can run the same code on the client as on the server.

    :trolleybus:

    So... Technically... Everything1 gets boiled down to Assembly/Machine code..... So....

    1inb4 $(obscure_language) doesn't, it uses $(wtf) to completely bypass the machine code



  • I'm not sure if you're able to run arbitrary machine code on the client, but I hope you aren't allowed to.


  • Winner of the 2016 Presidential Election

    @sloosecannon said:

    So... Technically... Everything1 gets boiled down to Assembly/Machine code..... So....

    Except Discourse. Discourse gets boiled down to rainbows:

    http://what.thedailywtf.com/t/vote-of-no-confidence/270/281?u=onyx


    Filed under: I'm sorry


  • Winner of the 2016 Presidential Election

    @ben_lubar said:

    I'm not sure if you're able to run arbitrary machine code on the client, but I hope you aren't allowed to.

    Well, technically Javascript eventually ends up calling something that's machine code


    Filed Under: This is my pendantry, ruin your own!



  • Go doesn't have that problem. Why do you think other languages do?


  • Winner of the 2016 Presidential Election

    Nobody wants to Go down that discussion path ben, leave it be.

    :rimshot:



  • I don't understand Node.JS so it probably sucks and it's definitely worse than what I'm already using!!!!!

    There I summed up this thread for you guys.



  • Thanks.



  • it is all good with node until your process reach 1.7gb on 64bit


  • mod

    @Onyx said:

    Filed under: I'm sorry

    You better be …



  • Paging @Groaner!



  • Not sure how good a benxhmark this is, since I'm not a player myself, but Ubisoft is using node.js for their server software.

    That and 2/3 of the world's cloud capacity.


  • sockdevs

    @Mikael_Svahnberg said:

    Ubisoft is using node.js

    That's enough for a lot of people to justify not using it!



  • @Mikael_Svahnberg said:

    Ubisoft is using node.js for their server software.

    I like node.js, and this still troubles me. I wonder which part of their infrastructure it's on...



  • I'll bite.

    If you are familiar with the architecture of nginx, you should know why it's faster than an equivalent multi-threaded/multi-process architecture. Nodejs uses the same model, single-threaded event-driven asynchronous workers. It just does it in javascript. If you don't know why nginx is faster, read this: https://anturis.com/blog/nginx-vs-apache/.

    Let me clarify this by saying that nodejs is NOT faster than an equivalent compiled program. You do not get speed by running your code in javascript. You get simple, easy scalability with nodejs. You don't have to worry about writing an event loop with asynchronous I/O because node has done that already. Given that most[citation needed] web applications are I/O bound, node allows them to scale with better performance than an architecture that is using thread pools or multiple processes. Try writing a multi-threaded websocket server in Java and see how well it scales.

    Node does not avoid context-switching on the CPU. That happens all the time on any modern operating system. It also does not avoid context-switching during development. You have different APIs on the browser, and you don't (usually) have a DOM in node.

    The argument for speeding up development is really distracting from the actual problem. If you have bad developers, you will suffer additional development time regardless of the language.

    TL;DR: Event-driven programming is better than threading for web-scale servers.



  • ... but you can run multiple instances of your nodejs/iojs service and load-balance between them!


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.