Saturday, March 26, 2011

Lazy Logging on Javascript

One of the things that I like about C/C++ is compile time macros. What they mean is that if I have debug print statements, not only will they be compiled out, but also the expressions passed to the printing statement will not be evaluated.

I have code like this in javascript:
var logging = false;
function log() {
  if (logging)
    console.log.apply(console, arguments);

var xml = an_xml_stanza();
log("XML Stanza:", xml.toString());

Even if logging is false, the expression xml.toString() will be evaluated, which can be quite costly in a production setup (I'm talking about node.js and not on a browser).

The way I've solved this is by making sure that my log() function can accept functions as well. Hence, code such as this becomes possible:

var xml = an_xml_stanza();
log(function() {
  return ["XML Stanza:", xml.toString()];

The log() function needs to be patched to look like this:
log = function() {
  if (!logging)

  if (arguments.length == 1 && typeof arguments[0] == "function")
    arguments = arguments[0]();

  console.log.apply(console, arguments);

This essentially means that you've gotten rid of the runtime cost of calling xml.toString() when logging is disabled.


XIX said...

We are kind of at the point where js should be "compiled" anyway.

Why not just run the js files through the c pre preprocessor...


dhruv said...

haha!! Yes, I guess people already do that in the "minification" step, so that is a very real possibility...