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
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.
xxxxxxxxxx
1
// configutarion
2
3
var testsCount = 1;
4
var testSize = 1000000;
5
6
// test
7
8
var result1 = { name: 'x = -x;', dt: 0 };
9
var result2 = { name: 'x *= -1;', dt: 0 };
10
var result3 = { name: 'x = ~x + 1;', dt: 0 };
11
12
var t1, t2;
13
var x = Math.round(1000 * Math.random());
14
15
for (var i = 0; i < testsCount; ++i) {
16
17
t1 = new Date();
18
for (var j = 0; j < testSize; ++j) {
19
x = -x;
20
}
21
t2 = new Date();
22
result1.dt += t2 - t1;
23
24
t1 = new Date();
25
for (var j = 0; j < testSize; ++j) {
26
x *= -1;
27
}
28
t2 = new Date();
29
result2.dt += t2 - t1;
30
31
t1 = new Date();
32
for (var j = 0; j < testSize; ++j) {
33
x = ~x + 1;
34
}
35
t2 = new Date();
36
result3.dt += t2 - t1;
37
}
38
39
// summary
40
41
var results = [ result1, result2, result3 ];
42
var max = results[0];
43
44
for (var i = 1; i < results.length; ++i) {
45
var result = results[i];
46
47
if (result.dt > max.dt) {
48
max = result;
49
}
50
}
51
52
console.log('x=' + x);
53
54
//console.log(result1.name + ' // ' + result1.dt + 'ms');
55
//console.log(result2.name + ' // ' + result2.dt + 'ms');
56
//console.log(result3.name + ' // ' + result3.dt + 'ms');
57
58
for (var i = 0; i < results.length; ++i) {
59
var result = results[i];
60
61
if(result == max) {
62
console.log(result.name + ' // ' + result.dt + 'ms');
63
} else {
64
var improvement = 100 * (max.dt - result.dt) / max.dt;
65
66
console.log( result.name
67
+ ' // ' + result.dt + 'ms'
68
+ ' -> ' + improvement.toFixed(2) + '% faster than ' + max.name);
69
}
70
}
Note: in the above code there are 2 configuration variables:
testsCount
- number of test repeats,testSize
- number of iterations per one test.
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
xxxxxxxxxx
1
# var testsCount = 1;
2
# var testSize = 100000000;
3
4
5
$ node Script.js
6
x=886
7
x = -x; // 130ms
8
x *= -1; // 114ms -> 12.31% faster than x = -x;
9
x = ~x + 1; // 119ms -> 8.46% faster than x = -x;
10
11
$ node Script.js
12
x=643
13
x = -x; // 158ms
14
x *= -1; // 121ms -> 23.42% faster than x = -x;
15
x = ~x + 1; // 138ms -> 12.66% faster than x = -x;
16
17
$ node Script.js
18
x=16
19
x = -x; // 134ms
20
x *= -1; // 117ms -> 12.69% faster than x = -x;
21
x = ~x + 1; // 124ms -> 7.46% faster than x = -x;
22
23
$ node Script.js
24
x=241
25
x = -x; // 141ms
26
x *= -1; // 122ms -> 13.48% faster than x = -x;
27
x = ~x + 1; // 124ms -> 12.06% faster than x = -x;
28
29
$ node Script.js
30
x=954
31
x = -x; // 145ms
32
x *= -1; // 117ms -> 19.31% faster than x = -x;
33
x = ~x + 1; // 121ms -> 16.55% faster than x = -x;
34
35
$ node Script.js
36
x=569
37
x = -x; // 138ms
38
x *= -1; // 124ms -> 10.14% faster than x = -x;
39
x = ~x + 1; // 117ms -> 15.22% faster than x = -x;
40
41
42
# summary
43
44
x = -x; // 0 points
45
x *= -1; // 5 points
46
x = ~x + 1; // 1 point
47
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
xxxxxxxxxx
1
# var testsCount = 1;
2
# var testSize = 100000000;
3
4
5
x=837
6
x = -x; // 324ms -> 4.14% faster than x = ~x + 1;
7
x *= -1; // 329ms -> 2.66% faster than x = ~x + 1;
8
x = ~x + 1; // 338ms
9
10
x=498
11
x = -x; // 326ms -> 3.26% faster than x = ~x + 1;
12
x *= -1; // 323ms -> 4.15% faster than x = ~x + 1;
13
x = ~x + 1; // 337ms
14
15
x=59
16
x = -x; // 331ms -> 2.07% faster than x = ~x + 1;
17
x *= -1; // 329ms -> 2.66% faster than x = ~x + 1;
18
x = ~x + 1; // 338ms
19
20
x=518
21
x = -x; // 324ms -> 5.81% faster than x = ~x + 1;
22
x *= -1; // 332ms -> 3.49% faster than x = ~x + 1;
23
x = ~x + 1; // 344ms
24
25
x=960
26
x = -x; // 327ms -> 4.66% faster than x = ~x + 1;
27
x *= -1; // 325ms -> 5.25% faster than x = ~x + 1;
28
x = ~x + 1; // 343ms
29
30
x=390
31
x = -x; // 336ms -> 2.61% faster than x = ~x + 1;
32
x *= -1; // 335ms -> 2.90% faster than x = ~x + 1;
33
x = ~x + 1; // 345ms
34
35
36
# summary
37
38
x = -x; // 2 points
39
x *= -1; // 4 points
40
x = ~x + 1; // 0 point
41
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
xxxxxxxxxx
1
# var testsCount = 1;
2
# var testSize = 100000000;
3
4
5
x=948
6
x = -x; // 205ms -> 14.58% faster than x = ~x + 1;
7
x *= -1; // 208ms -> 13.33% faster than x = ~x + 1;
8
x = ~x + 1; // 240ms
9
10
x=628
11
x = -x; // 197ms -> 13.97% faster than x = ~x + 1;
12
x *= -1; // 205ms -> 10.48% faster than x = ~x + 1;
13
x = ~x + 1; // 229ms
14
15
x=11
16
x = -x; // 199ms -> 13.85% faster than x = ~x + 1;
17
x *= -1; // 205ms -> 11.26% faster than x = ~x + 1;
18
x = ~x + 1; // 231ms
19
20
x=134
21
x = -x; // 205ms -> 17.00% faster than x = ~x + 1;
22
x *= -1; // 211ms -> 14.57% faster than x = ~x + 1;
23
x = ~x + 1; // 247ms
24
25
x=247
26
x = -x; // 208ms -> 13.33% faster than x = ~x + 1;
27
x *= -1; // 203ms -> 15.42% faster than x = ~x + 1;
28
x = ~x + 1; // 240ms
29
30
x=247
31
x = -x; // 208ms -> 13.33% faster than x = ~x + 1;
32
x *= -1; // 203ms -> 15.42% faster than x = ~x + 1;
33
x = ~x + 1; // 240ms
34
35
36
# summary
37
38
x = -x; // 4 points
39
x *= -1; // 2 points
40
x = ~x + 1; // 0 point
41
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
xxxxxxxxxx
1
# var testsCount = 1;
2
# var testSize = 100000000;
3
4
5
x=165
6
x = -x; // 993ms -> 0.20% faster than x *= -1;
7
x *= -1; // 995ms
8
x = ~x + 1; // 882ms -> 11.36% faster than x *= -1;
9
10
x=638
11
x = -x; // 994ms
12
x *= -1; // 993ms -> 0.10% faster than x = -x;
13
x = ~x + 1; // 878ms -> 11.67% faster than x = -x;
14
15
x=46
16
x = -x; // 996ms
17
x *= -1; // 992ms -> 0.40% faster than x = -x;
18
x = ~x + 1; // 868ms -> 12.85% faster than x = -x;
19
20
x=713
21
x = -x; // 1002ms
22
x *= -1; // 991ms -> 1.10% faster than x = -x;
23
x = ~x + 1; // 875ms -> 12.67% faster than x = -x;
24
25
x=256
26
x = -x; // 993ms
27
x *= -1; // 991ms -> 0.20% faster than x = -x;
28
x = ~x + 1; // 874ms -> 11.98% faster than x = -x;
29
30
x=873
31
x = -x; // 998ms
32
x *= -1; // 991ms -> 0.70% faster than x = -x;
33
x = ~x + 1; // 874ms -> 12.42% faster than x = -x;
34
35
36
# summary
37
38
x = -x; // 0 points
39
x *= -1; // 0 points
40
x = ~x + 1; // 6 point
41