Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

moment.js isAfter performance

I have my dates converted to moment.js, and now I want to compare it with another date ('now' in this case).

Just a plain compare with a date object seems to be a lot faster than using moment.js isAfter function.

  • Will this simple compare work in all locales?
  • Am I missing something here?
  • Is there a very specific reason why isAfter seems to create a new moment object instead of taking a shortcut when it's a Date object?

All my dates are in UTC.

function executeTests() {
  isAfterTest();
  compareTest();
}

function isAfterTest() {
  console.time('isAfterTest');

  var now = new Date();
  var dateOfBirth = moment('2000-01-01');

  for (var i = 0; i < 50000; i++) {
    var x = dateOfBirth.isAfter(now);
  }

  console.timeEnd('isAfterTest');
}

function compareTest() {
  console.time('compareTest');

  var now = new Date();
  var dateOfBirth = moment('2000-01-01');

  for (var i = 0; i < 50000; i++) {
    var x = dateOfBirth > now;
  }

  console.timeEnd('compareTest');
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.7.0/moment-with-langs.js"></script>
<button onclick="executeTests();">Run Test</button>

Results:

isAfterTest: 3754.000ms (index):32
compareTest: 24.000ms 

See: http://jsfiddle.net/t4grs0p7/2/

like image 339
Dirk Boer Avatar asked Aug 14 '14 14:08

Dirk Boer


1 Answers

Looking at the documentation http://momentjs.com/docs/ the isAfter method accepts different types of Date format:

moment().isAfter(Moment|String|Number|Date|Array);

This means it needs to do type checking and then convert it to a date object before running the calculation.

One way you could reduce this impact would be to pass in a Moment object as the comparison date:

function isAfterTest() {
    console.time('isAfterTest');

    var now = moment();
    var dateOfBirth = moment('2000-01-01');

    for (var i = 0; i < 50000; i++) {
        var x = dateOfBirth.isAfter(now);
    }

    console.timeEnd('isAfterTest');
}

I created a fiddle to compare, but that doesn't seem to improve it much at all: http://jsfiddle.net/kmturley/t4grs0p7/7/

Looking at your version I believe you should be using valueOf() method to compare the values:

window.compareTest2 = function() {
    console.time('compareTest2');

    var now = moment().valueOf();
    var dateOfBirth = moment('2000-01-01').valueOf();

    for ( var i = 0; i < 50000; i++ )
        var x = dateOfBirth > now;

    console.timeEnd('compareTest2');
}

Here is a working example: http://jsfiddle.net/kmturley/t4grs0p7/8/

like image 198
Kim T Avatar answered Sep 23 '22 15:09

Kim T