var bigInt32 = 2n ** 24n;
var bigInt64 = 2n ** 40n;
var bigInt128 = 2n ** 80n;
var bigIntNum = 2n ** 10n;
var int32 = 2 ** 10;
var int64 = 2 ** 40;
var float = Math.fround(2 ** 20);
var double = 2 ** 80;
var intNum = 2 ** 10;
const imul = Math.imul
const fround = Math.fround
let a = bigInt32;
let b = bigIntNum;
let c_sub, c_mod, c_mul, c_add;
c_sub = a - b > a;
c_mod = a % b < a;
c_mul = a * b === a;
c_add = a + b !== a;
let a = bigInt64;
let b = bigIntNum;
let c_sub, c_mod, c_mul, c_add;
c_sub = a - b > a;
c_mod = a % b < a;
c_mul = a * b === a;
c_add = a + b !== a;
let a = bigInt128;
let b = bigIntNum;
let c_sub, c_mod, c_mul, c_add;
c_sub = a - b > a;
c_mod = a % b < a;
c_mul = a * b === a;
c_add = a + b !== a;
let a = int32;
let b = intNum;
let c_sub, c_mod, c_mul, c_add;
c_sub = a - b > a;
c_mod = a % b < a;
c_mul = a * b === a;
c_add = a + b !== a;
"use asm";
let a = int32 | 0;
let b = intNum | 0;
let c_sub, c_mod, c_mul, c_add;
c_sub = a - b > a;
c_mod = a % b < a;
c_mul = imul(a, b);
c_add = a + b;
let a = int64;
let b = intNum;
let c_sub, c_mod, c_mul, c_add;
c_sub = a - b > a;
c_mod = a % b < a;
c_mul = a * b === a;
c_add = a + b !== a;
"use asm";
let a = float;
let b = fround(intNum);
let c_sub, c_mod, c_mul, c_add;
c_sub = fround(a - b) > a;
c_mod = fround(a % b) < a;
c_mul = fround(a * b) === a;
c_add = fround(a + b) !== a;
let a = double;
let b = intNum;
let c_sub, c_mod, c_mul, c_add;
c_sub = a - b > a;
c_mod = a % b < a;
c_mul = a * b === a;
c_add = a + b !== a;
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
BigInt (32) | |
BigInt (64) | |
BigInt (128) | |
Number (Int32) | |
Number (Int32 asm.js) | |
Number (maybe Int64) | |
Number (Float asm.js) | |
Number (Double) |
Test name | Executions per second |
---|---|
BigInt (32) | 175127632.0 Ops/sec |
BigInt (64) | 171538304.0 Ops/sec |
BigInt (128) | 166239408.0 Ops/sec |
Number (Int32) | 158601920.0 Ops/sec |
Number (Int32 asm.js) | 162291344.0 Ops/sec |
Number (maybe Int64) | 169008352.0 Ops/sec |
Number (Float asm.js) | 166076432.0 Ops/sec |
Number (Double) | 162630832.0 Ops/sec |
This benchmark tests the performance of various numeric data types in JavaScript, particularly comparing JavaScript's native Number
type (which represents double-precision floating point numbers) and the BigInt
type (for handling large integers) under different scenarios. Each test case examines basic arithmetic operations (subtraction, modulo, multiplication, and addition) using these data types and various strategies, including standard operations and operations optimized through asm.js
.
BigInt (32, 64, 128):
BigInt
(32-bit, 64-bit, and 128-bit). BigInts can represent integers larger than the maximum safe integer value for regular Numbers.let a = bigInt32; // Examples using BigInt (32)
let b = bigIntNum; // Another BigInt
Number (Int32):
let a = int32; // Standard Integer
let b = intNum; // Another Integer
Number (Int32 asm.js):
"use asm"
which is a directive in JavaScript that allows the performance optimizations of asm.js, a subset of JavaScript that can be optimized by proper JIT compilers."use asm";
let a = int32 | 0; // operations treated as integers
Number (maybe Int64):
Number (Float asm.js):
"use asm";
let a = float; // Float representations
asm.js
reduces versatility for other JavaScript features.Number (Double):
BigInt
is better; for speed, native integers (with potential asm.js
optimization) might be more suitable.Other alternatives could include using more advanced libraries that manage number precision and performance more effectively, such as:
This benchmark is significant in demonstrating how JavaScript’s handling of various numeric types impacts performance. It allows developers to make informed decisions on which numerical approach to adopt based on the requirements of their specific applications. Understanding these differences is crucial for optimizing performance in JavaScript applications that require significant numeric computations.