-
Notifications
You must be signed in to change notification settings - Fork 295
Description
Details
I encountered some performance slowdowns in Node.js 18.16 while developing for IOT devices.
To reproduce the problem, I wrote a simple prime number generation program:
C version, compiled with gcc -o prime prime1.c -O2 -lm
(all test platforms were 64-bit)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
int main() {
const long long Prime = 10000000;
long long sqrt_i, i, n, j;
float delta_sec;
struct timeval in_time, out_time;
n = 0;
gettimeofday(&in_time, NULL);
for (i = 3; i <= Prime; i = i + 2) {
sqrt_i = sqrt(i);
for (j = 2; j <= sqrt_i; j++)
if (i % j == 0) break;
if (j > sqrt_i) {
n++;
}
}
gettimeofday(&out_time, NULL);
delta_sec = (out_time.tv_sec - in_time.tv_sec) +
(out_time.tv_usec - in_time.tv_usec) * 1e-6;
printf("prime count: %lld delta sec: %.3f Sec\n", n, delta_sec);
printf("size of short:%d\n", sizeof(short));
printf("size of int:%d\n", sizeof(int));
printf("size of long:%d\n", sizeof(long));
printf("size of long long:%d\n", sizeof(long long));
printf("size of float:%d\n", sizeof(float));
printf("size of double:%d\n", sizeof(double));
}
JS version
const Prime = 10000000;
let sqrt_i;
let in_time, out_time;
let n = 0;
let i, j;
in_time = new Date().getTime();
nextPrime: for (i = 3; i <= Prime; i = i + 2) {
sqrt_i = Math.sqrt(i);
for (j = 2; j <= sqrt_i; j++) {
if (i % j == 0) break;
}
if (j > sqrt_i) n++;
}
out_time = new Date().getTime();
console.log(`Total time: ${(out_time - in_time) / 1000}S Total Prime: ${n}`);
JS version is almost as fast as C counterpart on Raspberry Pi 4B (overclocked, 2.0GHz)
pi@Pi-4B:~/devel/nodejs $ node --jitless prime.js
Warning: disabling flag --expose_wasm due to conflicting flags
Total time: 118.194S Total Prime: 664578
pi@Pi-4B:~/devel/nodejs $ node prime.js
Total time: 7.846S Total Prime: 664578
pi@Pi-4B:~/devel/nodejs $ ./prime
prime count: 664578 delta sec: 7.840 Sec
Running the same programs on Intel N4200, A72, and A76 CPUs yielded similar results.
However, JS version took nearly twice as much time as C version to execute on Raspberry Pi 3B+:
pi@Pi-3plus:~/devel/nodejs $ node --jitless prime.js
Warning: disabling flag --expose_wasm due to conflicting flags
Total time: 462.267S Total Prime: 664578
pi@Pi-3plus:~/devel/nodejs $ node prime.js
Total time: 29.455S Total Prime: 664578
pi@Pi-3plus:~/devel/nodejs $ ./prime
prime count: 664578 delta sec: 14.381 Sec
Same occurence was found on Rk3399 (2 A73 and 4 A53 cores, 4GB RAM):
pi@R4S:~/devel/nodejs$ taskset -c 5 node prime.js
Total time: 7.875S Total Prime: 664578
pi@R4S:~/devel/nodejs$ taskset -c 5 ./prime
prime count: 664578 delta sec: 7.717 Sec
pi@R4S:~/devel/nodejs$ taskset -c 0 node prime.js
Total time: 25.485S Total Prime: 664578
pi@R4S:~/devel/nodejs$ taskset -c 0 ./prime
prime count: 664578 delta sec: 12.402 Sec
as well as Rk3588S (4 A75 and 4 A55 cores, 16GB RAM):
firefly@firefly:~/nodejs$ taskset -c 6 ./prime
prime count: 664578 delta sec: 6.899 Sec
firefly@firefly:~/nodejs$ taskset -c 6 node prime.js
Total time: 6.868S Total Prime: 664578
firefly@firefly:~/nodejs$ taskset -c 2 ./prime
prime count: 664578 delta sec: 11.010 Sec
firefly@firefly:~/nodejs$ taskset -c 2 node prime.js
Total time: 22.605S Total Prime: 664578
and also on RK3308 (rockpi-s):
i@Pi-S:~/nodejs$ node prime.js
Total time: 36.975S Total Prime: 664578
pi@Pi-S:~/nodejs$ ./prime
prime count: 664578 delta sec: 16.707 Sec
I would like to know what caused this slowdown as well as how to optimize performance for A53 CPUs. Many thanks!
Node.js version
pi@R4S:~/devel/nodejs$ node -v
v18.16.0
pi@R4S:~/devel/nodejs$ apt show nodejs
Package: nodejs
Version: 18.16.0-deb-1nodesource1
Priority: optional
Section: web
Maintainer: Operations Nodesource <operations@nodesource.com>
Installed-Size: 186 MB
Provides: nodejs-dev, nodejs-doc, nodejs-legacy, npm
Depends: libc6 (>= 2.28), libgcc1 (>= 1:4.2), libstdc++6 (>= 5.2), python3-minimal, ca-certificates
Conflicts: nodejs-dev, nodejs-doc, nodejs-legacy, npm
Replaces: nodejs-dev (<= 0.8.22), nodejs-legacy, npm (<= 1.2.14)
Homepage: https://nodejs.org
Download-Size: 28.0 MB
APT-Manual-Installed: yes
APT-Sources: https://deb.nodesource.com/node_18.x focal/main arm64 Packages
Example code
No response
Operating system
pi@R4S:~/devel/nodejs$ uname -a
Linux R4S 5.15.11 #4 SMP PREEMPT Thu Jan 20 15:59:05 CST 2022 aarch64 aarch64 aarch64 GNU/Linux
pi@Pi-3plus:~ $ uname -a
Linux Pi-3plus 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux
Scope
Performance on Arm A53, A55, and A35 CPUs
Module and version
Not applicable.