4 ms·
> Somehow, since browsers are well accepted, node.js is a reasonable benchmark for embedded systems performance [3] NodeJS relies on V8, which is perhaps the w
by samhw 5y ago
> Somehow, since browsers are well accepted, node.js is a reasonable benchmark for embedded systems performance [3]
NodeJS relies on V8, which is perhaps the world's most highly optimised interpreter (/JIT compiler/runner), and a spectacular piece of software. The v8.dev blog alone is fantastic reading for anyone who works on compilers, as I do.
I don't like the 'dev' tendency in the programming community, to just hack stuff together and say "well, it works!", but I'm also not impressed by people trashing any high-level languages just because it's a meme they heard.
V8 is phenomenally performant and is a hard benchmark to beat for anyone and anything, even at the compiled end of the spectrum. (Yes, it's beaten by C/C++/Rust/Go, but it's not to be sneered at, at all.) I'm struggling to equal it with the highly optimised Python JIT-assisted interpreter I'm writing for my work - even after relaxing the ABI and writing sophisticated instruction-set-specific optimisations. (And I'm writing it in Rust, just to score at least one point off the cargo-cult bingo card.)
- jvanderbot 5y agoThat is impressive, and not unexpected given the (likely) billions of dollars of investment in things like nodejs. I did not mean to disparage it in itself just because it was developed for a particular domain. However, if "An embedded system uses the internet to communicate" has become synonymous with "It runs linux and uses web services and nodejs" then that would be a perfect example of contorting the application to match the technology that more programmers are most productive with.
- samhw 5y ago> I did not mean to disparage it just because it was developed for a particular domain. Fair enough, that's all I was saying. I'd agree with you that the increased use of Node everywhere to build applications, with tools like Electron, is an utterly stultifying trend. It's fantastic for I/O-heavy 'server'-type code, and for using JS as an at least surprisingly performant interpreted language, but it's disappointing to see it replacing languages like Swift or C++ in computation-heavy systems programming - or domains which should be the preserve of systems programmers. > However, if "An embedded system uses the internet to communicate" has become synonymous with "It runs linux and uses web services and nodejs" then that would be a perfect example of contorting the application to match the technology that more programmers are most productive with. I absolutely agree. No quibble with you there! I'm a fan of using the best tool for the job. And, much as it's a meme, I absolutely adore Rust for lots of systems programming applications. PS: If what you love about Rust is its safety even more than its speed, then I'd recommend looking into Ada, which could be called the precursor of Rust. It has none of Rust's modern trendiness, but it's a mindblowing accomplishment in TypeScript/Haskell-grade type expressivity (with Rust-grade safety) while still retaining I-believe-greater-than-Rust speed.
- KwisaksHaderach 5y agoIt's fantastic for I/O-heavy 'server'-type code I have found nodejs frustrating for CRUD APIs, the is 'fantastic for heavy I/O' while true ends up guiding you to complex microservices(or trying to use a external services for everything) because you don't want to slow down the event loop as you add more and more cpu processing to your app.
- udp 5y ago“More and more CPU processing” doesn’t sound like a CRUD API.
- newlisp 5y agoA CRUD API doesn't mean "just talks to the database and nothing more", a simple example and one of many is how PDF generation can f*ck up your event loop.
- eyelidlessness 5y agoIf your workload is actually CPU-heavy, Node’s solutions for this are several: - worker threads - child processes/IPC - native bindings (n-api/gyp/etc) - WASM/WASI Maybe so many as to cause choice/research paralysis. If you’re primarily interested in writing JS/TS, worker threads are a great option. And for most use cases you don’t need to worry about shared memory/atomics, postMessage has surprisingly good performance characteristics.
- KwisaksHaderach 5y agoWorkers threads spawn a new JS VM( which implies a new GC) for each worker! We tried it and the gains from parallelism stopped when there were half as many workers as CPUs.
- eyelidlessness 5y agoThey do create a new VM isolate. That’s a cost your workload will need to exceed before you get much if any benefit. As far as thread count, my default guidance is 50% of cores if your CPU has SMT/hyper threading, coreCount - 2 otherwise. Those numbers can go higher depending on how much of your workload is CPU-heavy. If you have an even mix of compute and IO, for example, your threads will frequently be idle/less contentious (same principle as the single threaded event loop). And if your workload is a queue of short lived, isolated steps, I also recommend pre-spawning idle threads (potentially well beyond that active maximum). Pre-warming those isolates can help as well, or isolating with vm APIs (eg SourceTextModule) instead. As with, well, everything: your mileage may vary, it depends on your actual bottlenecks and constraints, as well as your tolerance for tuning.
- patrec 5y ago> NodeJS relies on V8, which is perhaps the world's most highly optimised interpreter (/JIT compiler/runner), and a spectacular piece of software. Uhm, has V8 come anywhere near LuaJIT's performance by now? And LuaJIT is basically a one-man effort.
- samhw 5y agoSorry, I should have been clearer: I meant that it's had the most manpower dedicated to optimising it, not that it's necessarily the most optimal. It's hard to make apples-to-apples comparisons in that respect, given the significant differences between different language specifications. (For instance, it's hard for anyone to write a reference-compliant interpreter for Python which is as fast as the interpreter they could write for, say, Ada or Haskell.)
- danachow 5y agoWell you did say: “ NodeJS relies on V8, which is perhaps the world's most highly optimised interpreter (/JIT compiler/runner)” But even in manpower this is pretty hyperbolic compared to Java and .NET. There was probably more manpower in even some of the third party Java runtimes like Azul.
- samhw 5y ago> Well you did say: "NodeJS relies on V8, which is perhaps the world's most highly optimised interpreter (/JIT compiler/runner)" Yes, and that's exactly what I meant. It's undergone the most optimisation. That doesn't mean the result will necessarily be more performant than some other interpreter for a different language which is simpler to interpret. By that logic, I could write an 'x86 interpreter' which would blow LuaJIT out of the water... > But even in manpower this is pretty hyperbolic compared to Java and .NET. I wasn't including Java because it's not strictly an interpreted language, though I admit you could write a whole book about the philosophical differences between V8's abstract machine vs Java's bytecode VM. .NET I don't know so much about. As far as I'm aware, .NET hasn't had as much manpower invested, though Java has & would certainly beat V8 if you included it.
- VWWHFSfQ 5y agoIt's my understanding that LuaJIT still beats V8 Javascript by a considerable margin. And I would say that Lua and Javascript are roughly comparable languages so it's an apples-to-apples comparison. > V8, which is perhaps the world's most highly optimised interpreter (/JIT compiler/runner) I don't think this is true. It's very popular but LuaJIT is still more performant.
- samhw 5y agoSorry, you're the second person to say this, so clearly I didn't phrase my comment very well. I meant that it's the interpreter which has undergone the most optimisation, or alternatively which has had the most brainpower dedicated to optimising it. I don't mean that the resulting interpreter is the most performant interpreter in some given benchmark. Like I said in my other reply, I don't think that can possibly be a meaningful benchmark, given different languages have different grammars and semantics which have a huge effect on the possibility of writing a performant interpreter (see: Python). I can see that you preempt this point in your comment, but, I mean, what on earth does "roughly comparable languages" mean? Comparable how? Even superficially similar languages can have semantic differences which have a deep impact on optimisability. (For instance Python's C ABI, invisible to most end users, which notoriously limits interpreter implementations. Or its bytecode dispatch. Or its attribute dynamism, precluding memoisation of lookups. The possibility of `eval` is an enormous one too, which also applies to JS.)