EN
JavaScript - fastest way to negate number
4
points
In this article, we would like to show you how to negate numbers in JavaScript.
There are three ways to negate numbers:
x = -x
x *= -1
x = ~x + 1
1. Complexity analysis
x = -x
Ā operations:- read the value from the memory
- makeĀ theĀ value negation
- write the value to memory
x *= -1
Ā (x = x * (-1)
) operations:- read the value from the memory
- make theĀ multiplication by
-1
operation - write the value to memory
x = ~x + 1
Ā operations:- read the value from the memory
- make bitwise not operation
- make add
+1
operation - write the value to memory
Notes:
- multiplication operations are slower than bitwise and subtract operations,
- in this case interpreter / compliler can make some optimisation,
- amount of operations affects on performance,
- getting and setting variables from RAMĀ memory can be slow.
The best way is always to make a benchmark test.
2. Benchmark test exampleĀ
// ONLINE-RUNNER:browser;
// configutarion
var testsCount = 1;
var testSize = 1000000;
// test
var result1 = { name: 'x = -x;', dt: 0 };
var result2 = { name: 'x *= -1;', dt: 0 };
var result3 = { name: 'x = ~x + 1;', dt: 0 };
var t1, t2;
var x = Math.round(1000 * Math.random());
for (var i = 0; i < testsCount; ++i) {
t1 = new Date();
for (var j = 0; j < testSize; ++j) {
x = -x;
}
t2 = new Date();
result1.dt += t2 - t1;
t1 = new Date();
for (var j = 0; j < testSize; ++j) {
x *= -1;
}
t2 = new Date();
result2.dt += t2 - t1;
t1 = new Date();
for (var j = 0; j < testSize; ++j) {
x = ~x + 1;
}
t2 = new Date();
result3.dt += t2 - t1;
}
// summary
var results = [ result1, result2, result3 ];
var max = results[0];
for (var i = 1; i < results.length; ++i) {
var result = results[i];
if (result.dt > max.dt) {
max = result;
}
}
console.log('x=' + x);
//console.log(result1.name + ' // ' + result1.dt + 'ms');
//console.log(result2.name + ' // ' + result2.dt + 'ms');
//console.log(result3.name + ' // ' + result3.dt + 'ms');
for (var i = 0; i < results.length; ++i) {
var result = results[i];
if(result == max) {
console.log(result.name + ' // ' + result.dt + 'ms');
} else {
var improvement = 100 * (max.dt - result.dt) / max.dt;
console.log( result.name
+ ' // ' + result.dt + 'ms'
+ ' -> ' + improvement.toFixed(2) + '% faster than ' + max.name);
}
}
Note: in the above code there are 2 configuration variables:
testsCount
Ā - number of test repeats,testSize
Ā - number of iterations per one test.
Ā
2.1. Notebook: Xiaomi Mi 13 with NodeJS test results
This test has been made on PC with:
- OS: Windows 10 x64
- Program: NodeJS x64 v10.15.1
- CPU: Intel i5-6200uĀ (6th generation)
- RAM: DDR4 8GB 2133 MHz
- SSD: SAMSUNG MZVLV256HCHP-00000
# var testsCount = 1;
# var testSize = 100000000;
$ node Script.js
x=886
x = -x; // 130ms
x *= -1; // 114ms -> 12.31% faster than x = -x;
x = ~x + 1; // 119ms -> 8.46% faster than x = -x;
$ node Script.js
x=643
x = -x; // 158ms
x *= -1; // 121ms -> 23.42% faster than x = -x;
x = ~x + 1; // 138ms -> 12.66% faster than x = -x;
$ node Script.js
x=16
x = -x; // 134ms
x *= -1; // 117ms -> 12.69% faster than x = -x;
x = ~x + 1; // 124ms -> 7.46% faster than x = -x;
$ node Script.js
x=241
x = -x; // 141ms
x *= -1; // 122ms -> 13.48% faster than x = -x;
x = ~x + 1; // 124ms -> 12.06% faster than x = -x;
$ node Script.js
x=954
x = -x; // 145ms
x *= -1; // 117ms -> 19.31% faster than x = -x;
x = ~x + 1; // 121ms -> 16.55% faster than x = -x;
$ node Script.js
x=569
x = -x; // 138ms
x *= -1; // 124ms -> 10.14% faster than x = -x;
x = ~x + 1; // 117ms -> 15.22% faster than x = -x;
# summary
x = -x; // 0 points
x *= -1; // 5 points
x = ~x + 1; // 1 point
2.2. Notebook: Xiaomi Mi 13 with Google Chrome Browser test results
This test has been made on PC with:
- OS: Windows 10 x64
- Program: Google ChromeĀ Version 78.0.3904.97 (Official Build) (64-bit)
- CPU: Intel i5-6200uĀ (6th generation)
- RAM: DDR4 8GB 2133 MHz
- SSD: SAMSUNG MZVLV256HCHP-00000
# var testsCount = 1;
# var testSize = 100000000;
x=837
x = -x; // 324ms -> 4.14% faster than x = ~x + 1;
x *= -1; // 329ms -> 2.66% faster than x = ~x + 1;
x = ~x + 1; // 338ms
x=498
x = -x; // 326ms -> 3.26% faster than x = ~x + 1;
x *= -1; // 323ms -> 4.15% faster than x = ~x + 1;
x = ~x + 1; // 337ms
x=59
x = -x; // 331ms -> 2.07% faster than x = ~x + 1;
x *= -1; // 329ms -> 2.66% faster than x = ~x + 1;
x = ~x + 1; // 338ms
x=518
x = -x; // 324ms -> 5.81% faster than x = ~x + 1;
x *= -1; // 332ms -> 3.49% faster than x = ~x + 1;
x = ~x + 1; // 344ms
x=960
x = -x; // 327ms -> 4.66% faster than x = ~x + 1;
x *= -1; // 325ms -> 5.25% faster than x = ~x + 1;
x = ~x + 1; // 343ms
x=390
x = -x; // 336ms -> 2.61% faster than x = ~x + 1;
x *= -1; // 335ms -> 2.90% faster than x = ~x + 1;
x = ~x + 1; // 345ms
# summary
x = -x; // 2 points
x *= -1; // 4 points
x = ~x + 1; // 0 point
2.3. Notebook: Xiaomi Mi 13 with Waterfox (64-bit Firefox) Browser test results
This test has been made on PC with:
- OS: Windows 10 x64
- Program: Waterfox 56.2.12 (64-bit)
- CPU: Intel i5-6200uĀ (6th generation)
- RAM: DDR4 8GB 2133 MHz
- SSD: SAMSUNG MZVLV256HCHP-00000
# var testsCount = 1;
# var testSize = 100000000;
x=948
x = -x; // 205ms -> 14.58% faster than x = ~x + 1;
x *= -1; // 208ms -> 13.33% faster than x = ~x + 1;
x = ~x + 1; // 240ms
x=628
x = -x; // 197ms -> 13.97% faster than x = ~x + 1;
x *= -1; // 205ms -> 10.48% faster than x = ~x + 1;
x = ~x + 1; // 229ms
x=11
x = -x; // 199ms -> 13.85% faster than x = ~x + 1;
x *= -1; // 205ms -> 11.26% faster than x = ~x + 1;
x = ~x + 1; // 231ms
x=134
x = -x; // 205ms -> 17.00% faster than x = ~x + 1;
x *= -1; // 211ms -> 14.57% faster than x = ~x + 1;
x = ~x + 1; // 247ms
x=247
x = -x; // 208ms -> 13.33% faster than x = ~x + 1;
x *= -1; // 203ms -> 15.42% faster than x = ~x + 1;
x = ~x + 1; // 240ms
x=247
x = -x; // 208ms -> 13.33% faster than x = ~x + 1;
x *= -1; // 203ms -> 15.42% faster than x = ~x + 1;
x = ~x + 1; // 240ms
# summary
x = -x; // 4 points
x *= -1; // 2 points
x = ~x + 1; // 0 point
2.3. Smartphone: Xiaomi Mi 5 Pro with Google Chrome Browser test results
This test has been made on phone with:
- OS: Android 8.0.0 (MIUI Global 10.2 | Stable)
- Program: Google Chrome
- CPU: Qualcomm Snapdragon 820 8996
- RAM: 3GB
- SSD/FLASH: 60GBĀ
# var testsCount = 1;
# var testSize = 100000000;
x=165
x = -x; // 993ms -> 0.20% faster than x *= -1;
x *= -1; // 995ms
x = ~x + 1; // 882ms -> 11.36% faster than x *= -1;
x=638
x = -x; // 994ms
x *= -1; // 993ms -> 0.10% faster than x = -x;
x = ~x + 1; // 878ms -> 11.67% faster than x = -x;
x=46
x = -x; // 996ms
x *= -1; // 992ms -> 0.40% faster than x = -x;
x = ~x + 1; // 868ms -> 12.85% faster than x = -x;
x=713
x = -x; // 1002ms
x *= -1; // 991ms -> 1.10% faster than x = -x;
x = ~x + 1; // 875ms -> 12.67% faster than x = -x;
x=256
x = -x; // 993ms
x *= -1; // 991ms -> 0.20% faster than x = -x;
x = ~x + 1; // 874ms -> 11.98% faster than x = -x;
x=873
x = -x; // 998ms
x *= -1; // 991ms -> 0.70% faster than x = -x;
x = ~x + 1; // 874ms -> 12.42% faster than x = -x;
# summary
x = -x; // 0 points
x *= -1; // 0 points
x = ~x + 1; // 6 point