Elliot B.
Elliot B.

Reputation: 17681

Optimizing JavaScript code that lowercases JSON property names

I working on a web application that receives JSON data with uppercase property names. I need those property names to be lowercase, so I'm using a function to loop recursively through the JSON object and convert them to lowercase.

The problem is my JSON replies can get very large. I want the function to perform well even if it has to process JSON with 60,000 property names and various levels of nesting.

The lowercasing function is:

FN = function (obj)
{var ret = null;
    if (typeof(obj) == "string" || typeof(obj) == "number")
        return obj;
    else if (obj.push)
        ret = [];
    else
        ret = {};
    for (var key in obj)
        ret[String(key).toLowerCase()] = FN(obj[key]);
    return ret;
};

And I'm performing some benchmarking here: http://jsfiddle.net/emw89/7/

The above test clocks in at ~570ms on my machine.

Is there anything I can do to improve the performance of this function?

Edit: I closed my IE, re-opened IE and ran the jsfiddle benchmark again--it's now coming in at ~180ms for me. My IE had been open for a couple days straight until just then, so maybe that's what was causing such poor performance. Either way, I'm still interested if there's a way to optimize this function further. Any time extra time spent processing JSON directly adds to the elapsed time of every AJAX request.

Upvotes: 7

Views: 2964

Answers (3)

Michal
Michal

Reputation: 13649

If you are processing large JSON objects with IE (or any other browser - but IE is most likely to spit the dummy) I recommend processing your json/array in chunks.

Good explanation of that process can be found here http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html (scroll down to the "Timer Patterns for Yielding" heading)

Upvotes: 1

usr
usr

Reputation: 171216

var lowerCache = {};

FN = function (obj)
{
    if (typeof(obj) === "string" || typeof(obj) === "number")
        return obj;

        var l = obj.length;
    if (l) {
        l |= 0;
        var result = [];
        result.length = l;
        for (var i = 0; i < l; i++) {
            var newVal = obj[i];
            result[i] = typeof(newVal) === "string" ? newVal : FN(newVal);
        }
        return result;
    } else {
     var ret = {};
     for (var key in obj) {

         var keyStr = typeof(key) === "string" ? key : String(key);
         var newKey = lowerCache[keyStr];
         if (newKey === undefined) {
             newKey = keyStr.toLowerCase();
             lowerCache[keyStr] = newKey;
         }

         var newVal = obj[key];
         ret[newKey] = typeof(newVal) === "string" ? newVal : FN(newVal);
     }
     return ret;
    }
};

100% faster.

Upvotes: 5

Senad Meškin
Senad Meškin

Reputation: 13756

I would do it with the simple regex replace.

  1. Use JSON to convert object to string
  2. Replace all properties with the same name just lowercase
  3. Convert string again into object

e.g.

var obj = { SENAD: "meskin" };

var str = JSON.stringify(obj);

function lCase(xxx)
{
    pattern = /\"([a-z0-9_-]{0,})\"\:/gi;
    return  xxx.replace(pattern, function() { return arguments[0].toLowerCase() });
}
str = lCase(str);

var newObj = JSON.parse(str);
alert(newObj.senad);
console.log(str);

I Hope this helps.

Upvotes: 3

Related Questions