Оптимизация кода JavaScript, который в нижнем регистре имен свойств JSON - PullRequest
7 голосов
/ 24 февраля 2012

Я работаю над веб-приложением, которое получает данные JSON с именами свойств в верхнем регистре.Мне нужно, чтобы имена этих свойств были строчными, поэтому я использую функцию для рекурсивного цикла по объекту JSON и преобразования их в строчные.

Проблема в том, что мои ответы JSON могут быть очень большими.Я хочу, чтобы функция работала хорошо, даже если она должна обрабатывать JSON с 60000 именами свойств и различными уровнями вложенности.

Функция нижнего регистра:

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;
};

И я выполняю некоторыебенчмаркинг здесь: http://jsfiddle.net/emw89/7/

Вышеупомянутый тест работает на моей машине на ~ 570 мс.

Могу ли я что-нибудь сделать, чтобы улучшить производительность этой функции?Редактировать: я закрыл свой IE, снова открыл IE и снова запустил бенчмарк jsfiddle - теперь он составляет ~ 180 мс для меня.Мой IE был открыт в течение пары дней до этого момента, так что, возможно, именно это и привело к такой низкой производительности.В любом случае, мне все еще интересно, есть ли способ оптимизировать эту функцию дальше.Каждый раз, когда дополнительное время затрачивается на обработку, JSON напрямую добавляется к истекшему времени каждого запроса AJAX.

Ответы [ 3 ]

5 голосов
/ 24 февраля 2012
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% быстрее.

3 голосов
/ 24 февраля 2012

Я бы сделал это с простой заменой регулярных выражений.

  1. Используйте JSON для преобразования объекта в строку
  2. Заменить все свойства с тем же именем только в нижнем регистре
  3. Снова преобразовать строку в объект

, например

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);

Надеюсь, это поможет.

1 голос
/ 24 февраля 2012

Если вы обрабатываете большие объекты JSON с помощью IE (или любого другого браузера - но IE, скорее всего, плюет на пустышку), я рекомендую обрабатывать ваш json / массив порциями.

Хорошее объяснение этого процесса можетнайти здесь http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html (прокрутите вниз до заголовка «Шаблоны таймеров для получения»)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...