Moment.js format performance on Node

October 6th 2017

Tags: node, javascript

Since my last post (years ago) was about expounding the virtues of moment.js for browser compatibility, here's the other side of the coin. If we just blindly use our favorite date library for everything, it doesn't always work out.

I was recently asked why a Node function which generates tens of thousands of objects was running slowly. A 100,000 element run was taking over a minute to process.

The hot loop had code that looked like this:

var dt = moment.utc(somedatestring);
var resObj = {
  date: dt.format('YYYY-MM-DD');

After a little profiling we discovered that moment.js parsing and formatting were taking 70% of the time in the function! This function was only using moment.js to parse and format the date. Further; the dates being parsed were guaranteed to be ISO8601 datetime strings. I came up with a benchmark to see if using native Dates and manual formatting would be any faster:

The results on my machine with Node v8.6.0:

moment#format x 0.41 ops/sec ±0.92% (6 runs sampled)
moment manual x 0.44 ops/sec ±1.71% (6 runs sampled)
moment manual + padStart x 0.44 ops/sec ±1.81% (6 runs sampled)
Date manual x 11.04 ops/sec ±1.87% (31 runs sampled)
Date manual + padStart x 11.09 ops/sec ±2.62% (32 runs sampled)
Date split x 6.18 ops/sec ±1.41% (20 runs sampled)
Fastest is Date manual,Date manual + padStart

Not only faster, but 27 times faster to use Date with manual formatting!

I'm not espousing that people write ugly date formatting code. I think that "make it work, then make it fast" is the right thing to do, and it worked here. Profiling and testing our assumptions led us to the fastest implementation. The resulting function now takes 8 seconds for a 100,000 element run.

By Colin Kennedy