NodeJS vs Java! An epic battle, which is going to rule in 2020! Part 1
Who is going to rule the programming world in the year 2020! Especially in a large enterprise application environment.
To be honest its a jungle out there with so many powerful creatures. However, there are two programming languages which are hard for any professional software developer or tech companies to ignore: Java and Javascript (not necessarily in that order :)
So which one is better? Moreover, which one is going to win the battle in 2020
To get an answer to these questions, one needs to understand the fundamentals on which establishes these languages and how they work with the underlying Operating System.
With powerful tools and simple linguistic, a programming language aims to make the life of a developer easy. The other important aspect of a programming language is the performance, how good a software performs in a given situation.
Let’s start with the performance.
Performance
No one disagrees to the need for a performant system.
But how one can define performance? How can it be measured? Well, it is not that complex to investigate if one gets these critical factors -
1. Computation Speed
2. Concurrency and
3. Input-Output or IO in short
Back to school!
Remember Space-Time computation complexity and Big O notation? No, we are not going back to school. However, this is how one calculates computation performance.
In other words, it is about how efficient is software in utilising the available resources Memory (Space) and CPU (Time)
All high-level programming languages access these underlying resources via the Operating System’s API. Let take a quick recap of some of these concepts
- Threads and Processes
- Multi-threading
- System I/O — BIO and NIO
Threads & Processes
A thread is a basic unit of CPU utilisation, a sequence of programmed instructions processed by a CPU.
A process is an instance of a computer program that is getting executed. A process can have one or many threads (Multi-threading). For example, when one launches a Notepad instance, it creates a process spawning many threads internal to it
Below attached is the screenshot of Activity Monitor showing different processes and associated running threads
Multi-threading —
A multi-threaded programming model is one where threads can be spawned/created at the runtime as per requirement
System I/O
IO is the communication between multiple processing systems. Example of such systems are CPU, keyboard, a network card (internet), an HTTP Server, a DB server or even a harddisk
Blocking vs Non-blocking IO —
A blocking IO means that a given thread cannot do anything more until the IO is fully received (in the case of sockets this wait could be a long time). Non-blocking IO means an IO request is queued straight away and the function returns. The actual IO is then processed at some later point by the kernel
Let us introduce the two candidates
Java
Java is a general-purpose programming language. It is class-based object-oriented in designed. It is, write once, runs anywhere (WORA) paradigm.
JVM — Java applications are typically compiled to bytecode that can run on any Java virtual machine (JVM) regardless of the underlying computer architecture.
Java exposes OS threads directly to the program which makes it a powerful multi-threading platform
Javascript
JavaScript often abbreviated as JS, is a high-level, interpreted scripting language that conforms to the ECMAScript specification.
As a multi-paradigm language, JavaScript supports event-driven, functional, and imperative (including object-oriented and prototype-based) programming styles.
Unlike Java, JS is directly interpreted by JS engines like NodeJS, V8(chrome), SpderMonkey(Mozilla) etc., without the need for compilation
Nodejs — As an asynchronous event-driven JavaScript runtime, Node.js is designed to build scalable network applications.
JavaScript was not designed to be categorised in programming styles (Functional/Object Oriented). A developer is free to align the coding strategy towards any programming styles. Some prefer the object-oriented style and others in the functional style. This flexibility is all about JavaScript’s dynamism.
Let us see how Java and JS manage the performance factors mentioned earlier.
I/O
Although Java introduced NIO a few years ago, still many de facto frameworks do not leverage it at all. Example, the servlet spec, Java’s de facto standard for writing backend server code. The spec at its core expects blocking subsequent calls. Another example is JDBC spec, again a de facto enterprise database interface for Java has blocking APIs.
This means even if one tries to use java NIO calls lets say with File operations, it will end up blocking at Servlet level. Quite a misfortune with Java community.
JavaScript, on the other hand, is designed around the event-based system. A reactive approach at its core, which means to act only when some event happens. Almost all the IO operations occur at the OS native level, and the intermittent status is transferred to the JS engine via events. It embraces non-blocking APIs at all levels.
That means that NodeJS will never be blocked while IO operations are being performed (unless one writes the code to block deliberately). As a result, most of the Server’s processing power& memory resources are utilised efficiently. It can handle and issue thousands of IO operations at once with only a single thread.
Concurrency
Java and NodeJS achieve concurrency in the web frameworks in two very different ways.
Java creates a new thread for each incoming request. The number of threads increases as concurrent requests grows.
NodeJS, on the other hand, processes all incoming requests in a single thread. As NodeJS embraces Non-blocking IO, it can perform all transformations/computations needed to handle the request while waiting for any IO events.
So when it comes to simple IO operations, Nodejs is a winner as it does not lock the processes, so there are almost no dead-locks. This makes NodeJS a right candidate for an extensive scalable system
Computation
Although NodeJS has a good eventing model which makes it a better player in IO and events based system, however when it comes to pure computation, Java still leads the way.
While today’s Javascript engines along with NodeJS are ever-evolving still it lacks simple memory management which is a tradeoff for being a dynamically typed language.
So if one wants a heavy computation, say calculating the Cryptographic keys or process a big chunk of text data; Java would be a better choice.
Web Application dominance
The defacto way for delivering a majority of software services is via Server-Client architecture; in other words, Cloud service interfaces with their users via web client ( Browsers or Apps). So it becomes essential to understand Web environments.
IO at every level
With the emergence of Microservices as a backbone of any largescale cloud solution, the Web technology solutions are full of I/O operations.
E.g.:
- A browser requests data or a page from the server
- Gateway server receives the request and sends subsequent requests to fetch data (database calls) or delegates to another microservice
- Once the response is ready, it is sent back to the browser
Web applications spend most of the time doing IO and not computation.
This makes NodeJS more preferable choice for Client facing servers
Scale!
No system design is complete today if scalability is not considered or tested. Today scalability is not luxury but a strict necessity.
As discussed earlier, Java dedicates a minimum one thread per request. This becomes a problem when load increases as the Operating System become too busy handling these threads and time slicing between them.
The efficiency of Node becomes apparent at scale. When NodeJS is running at max load, although the CPU will be very busy, the operating system won’t even break a sweat. All of the CPU time will be spent doing what you want, servicing requests.
So which one is better? Well, not so fast!
Remember, the software is ever-evolving in nature. There are lots of features and improvements added to each language spec that one should know of before making any perception.
So far, we have only discussed limited performance factors(as NIO aspects of JAVA is not covered). Now let’s dive into some of the linguistic paradigms of Java and JS in the next article.