Should Node.js be built with ClangCL under Windows?

Under Windows, when using Visual Studio to build C++ code, there are two possible compiler strategies. The Visual Studio compiler (often referred to as MSVC) is the default compiler provided by Microsoft for Windows development. In Debug mode, the regular Visual Studio compiler produces faster compilation times and more performant code compared to ClangCL. ClangCL is part of the Clang/LLVM project, which is an open-source compiler toolchain. ClangCL is compatible with the Visual Studio runtime and links with the Microsoft implementation of the Standard Library. It’s available as an optional component in Visual Studio 2019 and later versions.

In Debug mode, I find that the regular Visual Studio compiler builds faster. However, in release mode, I found empirically that ClangCL approach may provide more performant code. On some micro-benchmarks, the difference can be large (e.g., 40%) although I expect more modest gains on complex systems.

As of Chrome 64, Google Chrome for Windows is compiled with ClangCL. Thus Clang is now used to build Chrome for all platforms it runs on, including macOS, iOS, Linux, Chrome OS, Android, and Windows. Firefox switched to ClangCL in 2018. And at least some game developers have adopted ClangCL.

Node.js is an open-source, cross-platform JavaScript runtime environment. It allows developers to execute JavaScript code outside of a web browser. Unlike traditional JavaScript, which primarily runs in browsers, Node.js enables server-side execution of JavaScript. Node.js is part of popular web development stacks Node.js relies on the Google Chrome V8 JavaScript Engine: Node.js is built on the V8 JavaScript engine, the same engine used by Google Chrome.

Node.js is built under Windows using the regular Visual Studio compiler. Thanks in large part to Michaël Zasso, it is possible to build the Node.js under Windows with ClangCL. Could it improve the performance?

To start answering this question, I ran the standard V8 benchmarks from Node.js. These benchmarks mostly focus on V8 performance and are not affected by changes in other components. For my tests, I use Visual Studio 2022 on Microsoft Surface Laptop Studio.

All results point at improvements. That is, on average, the speed is greater with ClangCL than using the standard Visual Studio compiler. However, there is much noise in my numbers. Using the V8 benchmarks, only one test was statistically strong (serialize.js len=256).

function improvement
v8\get-stats getHeapSpaceStatistics 3% +/- 11%
v8\get-stats getHeapStatistics 10% +/- 11%
v8\serialize.js len=256 6% +/- 2%
v8\serialize.js len=16384 2% +/- 2%
v8\serialize.js len=524288 19% +/- 50%

I should stress that compilers have strengths and weaknesses. The regular Visual Studio compiler is perfectly capable and you should expect it to do better in some instances. And Microsoft have some of the best compiler engineers in the world: each new version might bring in improvements.

Furthermore, some tasks and benchmarks are not necessarily affected by the choice of a compiler: e.g., a network access, a disk processing routine, or a memory allocation stress test.

Yet it appears that there might be benefits to a transition to ClangCL for Node.js.

Daniel Lemire, "Should Node.js be built with ClangCL under Windows?," in Daniel Lemire's blog, May 2, 2024.

Published by

Daniel Lemire

A computer science professor at the University of Quebec (TELUQ).

2 thoughts on “Should Node.js be built with ClangCL under Windows?”

  1. The elephant in the room is that V8 is a JIT VM, which means that it translates (most) Javascript code to native instructions, and while the performance of the code generator itself depends on compiler optimizations, the generated code would be identical, regardless of the compiler used to compile V8 itself.

    The degree to which compiler optimizations can improve application performance depends on what percentage of CPU time is spend outside the JIT-generated code. That’s very application dependent.

    The V8 benchmarks might not be the best proxy for application performance either. I suspect a lot of those benchmarks are primarily exercising the JIT-generated code (i.e., they want to show how good the JIT compiler is at generating fast code) while real-world applications may well call into native components more often.

    I think this is a case where micro-benchmarks are much less informative than profiling real-world applications would be. Maybe some big corporation that uses a Node stack can try to replicate your experiment. But that raises another question: how common is it to run Node.js in production on Windows machines?

    1. The elephant in the room is that V8 is a JIT VM, which means that it translates (most) Javascript code to native instructions

      This will vary depending on the benchmark and I don’t know what is the case what I benchmarked, but V8 and Node have a lot of code written in C++. All the string implementation is in C++, and so forth.

      The Bun JavaScript runtime is sometimes several times faster than Node.js, and I do not think that’s because it has a massively better JIT compiler.

      But I did not consider your point earlier and it is a good one. When the test is stressing the JIT compiled code, then you should expect little dependence on the compiler.

Leave a Reply

Your email address will not be published.

You may subscribe to this blog by email.