Languages
[Edit]
EN

JavaScript - fastest way to negate number

4 points
Created by:
Marcin
2447

In JavaScript it is possible to negate numbers in following ways:

  1. x = -x
  2. x *= -1
  3. x = ~x + 1

1. Complexity analysis

  1. x = -x operations:
    1. read value from memory
    2. make value negation
    3. write value to memory
  2. x *= -1 (x = x * (-1)) operations:
    1. read value from memory
    2. make multiplication by -1 operation
    3. write value to memory
  3. x = ~x + 1 operations:
    1. read value from memory
    2. make bitwise not operation
    3. make add +1 operation
    4. write 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 perfomrance,
  • 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: inside above code are placed 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

 

Hey ūüĎč
Would you like to know what we do?
  • Dirask is a friendly IT community for learners, professionals and hobbyists to share their knowledge and help each other in extraordinary easy way.
  • We welcome everyone,
    no matter what the experience,
    no matter how basic the question is,
    this community will help you.