Number formatting with commas

JavaScript performance comparison

Revision 2 of this test case created by runsun

Info

to check the performance of regex over a native method Number.toLocaleString() and an array based implementation for number formatting in JavaScript.

Edit (v2):

  1. In previous jsperf, functions to be compared are defined inside test code. It means that it is not only comparing how fast those functions executes, but also how fast those functions are defined, which I believe is less interested to us. So they are moved to the Preparation code HTML section in this version.

  2. Add an event handler for each test-case to check if the outcome is correct. Turn on console to observe it.

  3. In all functions, use ''+num instead of num.toString() to speed it up.

  4. Extend the decimal part from .53 to .53880934 to see if that part can be handled correctly;

  5. Add an event handler to let console report results for easy copy/past.

  6. Add my function commafy. Using char scan, it shows very promising performance.

    Result when tested with Chrome 28 on Linux:

    1. without regex = 343,535,353.53880936 ops/sec= 123,534
    2. with regex = 343,535,353.53880936 ops/sec= 192,796
    3. toLocaleString= 343,535,353.539 ops/sec= 41,563
    4. commafy = 343,535,353.53880936 ops/sec= 409,303

# Note: Following the discussion in http://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript

Preparation code

<script>
var number = 343535353.53880934, v;

function formatNumber(num) {
  var decimalPart = '';
  num = ''+num;
  if (num.indexOf('.') != -1) {
    decimalPart = '.' + num.split('.')[1];
    num = parseInt(num.split('.')[0]);
  }
  var array = (''+num).split('');
  var index = -3;
  while (array.length + index > 0) {
    array.splice(index, 0, ',');
    index -= 4;
  }
  return array.join('') + decimalPart;
};

function formatNumberRgx(num) {
  var parts = (''+num).split(".");
  parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  return parts.join(".");
};

function commafy( num){
  var parts = (''+num).split("."), s=parts[0], i=L= s.length, o='',c;
  while(i--){ o = (i==0?'':((L-i)%3?'':','))
                 +s.charAt(i) +o }
  return o+'.'+parts[1]
}

ui.events.start.push( function(){
                      console.log('\n\n Testing start, number='
                                 + number+'\n\n' ) } )

for( var i=0, tcase; tcase=ui.benchmarks[i]; i++ )
{
     if(window.console) tcase.events.complete=[
       function(){
                this.funcReturn = v;
                console.log( '== test #'+ this.id
                + ' ('+ this.name + ') complete'
                + ', v= '+ v
                )
       }
     ]  
}

ui.events.complete.push(
   function(){
      console.log('\n\n Result:\n'  );
      var tcases = ui.benchmarks;
      var out= Array( tcases.length );
      for( var i=0, tcase; tcase=tcases[i]; i++ )
      {
         console.log( tcase.name + ' = '
                    + tcase.funcReturn + ', ops/sec= '
                    + commafy( (''+tcase.hz).replace(/^\s*/,'')).split('.')[0]
                    )
      }
   }
)
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
1. without regex
v= formatNumber(number);
pending…
2. with regex
v= formatNumberRgx(number);
pending…
3. toLocaleString
v= number.toLocaleString();
pending…
4. commafy
v= commafy(number);
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:

0 comments

Add a comment