Math.abs vs bitwise (v7)

Revision 7 of this benchmark created on


Description

Checking performance differences between Math.abs and using Bitwise manipulation.

Updates from previous revision:

1) None of the previous revisions used negative numbers for their test data, and so cannot be considered as accurate.

2) Switched the for..loop code in each test for a counter to remove the loop-within-a-loop, while still ensuring each test uses the same data.

3) Removed the tests that cached the Math object and Math.abs function, as they were slower than the bitwise version in every result.

4) Added 3 new methods from the article and associated user feedback here.

Note: The 3 new methods, abs2(), abs3(), and abs4(), are NOT suitable for use with floating point numbers. abs2() will truncate all f.p. numbers; abs3() and abs4() will truncate negative f.p. numbers. If this is not desirable, stick with the existing method, which I've renamed to abs1().

Preparation HTML

<script type="text/javascript">

        var nums = [];
        var numIndex;

        var largestDeltaFromZero = 1000;        // Values are in the range -1000 to +1000

        for (var loop=0; loop<1000; loop++) {
                var theVal = Math.random() * largestDeltaFromZero * 2 - largestDeltaFromZero;
                nums.push(theVal);
        }

        // Existing method from previous revisions. Works with both integer and floating point numbers
        function abs1(x) {
                return (x < 0 ? -x : x);
        }

        // New method. Truncates all floating point numbers to integers
        function abs2(x) {
                return (x ^ (x >> 31)) - (x >> 31);
        }

        // New method. Truncates negative floating point numbers to integers
        function abs3(x) {
                return (x < 0) ? (~x + 1) : x
        }

        // New method. Truncates negative floating point numbers to integers
        function abs4(x) {
                return (x <= 0) ? (~x + 1) : x;
        }

        // Native JS implementation test.
        var abs5 = Math.abs;
</script>

Setup

numIndex = nums.length - 1;

Test runner

Ready to run.

Testing in
TestOps/sec
abs1
if (!numIndex) numIndex = nums.length - 1;
var num = nums[numIndex--];
var absNum = abs1(num);
 
ready
abs2
if (!numIndex) numIndex = nums.length - 1;
var num = nums[numIndex--];
var absNum = abs2(num);
 
ready
abs3
if (!numIndex) numIndex = nums.length - 1;
var num = nums[numIndex--];
var absNum = abs3(num);
 
ready
abs4
if (!numIndex) numIndex = nums.length - 1;
var num = nums[numIndex--];
var absNum = abs4(num);
 
ready
Math.abs
if (!numIndex) numIndex = nums.length - 1;
var num = nums[numIndex--];
var absNum = abs5(num);
 
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.