Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 321
Elliot B. Avatar asked Feb 23 '12 21:02

Elliot B.


2 Answers

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.

like image 68
usr Avatar answered Oct 07 '22 03:10

usr


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.

like image 29
Senad Meškin Avatar answered Oct 07 '22 01:10

Senad Meškin