Как я могу ускорить этот разбор даты JSON? - PullRequest
0 голосов
/ 23 марта 2011

Я застрял, используя библиотеку AJAX около 5 лет назад в этом проекте, и у него были некоторые проблемы с датами разбора в JSON. Я переписал его функцию разбора для использования одного регулярного выражения:

return eval('(' + (enableDateParsing ? text.replace(/"(?:\\)?\/Date\((.*?)\)(?:\\)?\/"/g, "new Date($1)") : text) + ')');

Это работает очень хорошо, но я подумал, что смогу ускориться, если бы использовал собственный разбор JSON в IE8 / chrome / ff, поэтому добавил этот бит:

if (typeof JSON !== 'undefined' && typeof JSON.parse !== 'undefined') {     
        var nativeJsonDateParseRegex = /\/Date\(.*?\)\//g;       
        return JSON.parse(text, function (key, value) {
            if (AjaxPro.enableDateParsing && typeof value === 'string' && value.match(nativeJsonDateParseRegex)) 
            {
                value = new Date(parseInt(value.substr(6)));
            }                       
            return value;         
        });        
    } 
else // revert to eval for ie6/ie7

Обратный вызов reviver будет выполняться один раз для каждого возвращаемого свойства JSON, поэтому он должен быть очень быстрым. Во время просмотра профиля он вызывался 170484 раза, но все еще работает довольно быстро (131.237 мс). Любые идеи о том, как сделать это быстрее, или это лучшее, что вы можете сделать без серьезных настроек?

Ответы [ 2 ]

1 голос
/ 23 марта 2011

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

Предложения:

  • проверить поддержку собственного JSPNпри загрузке страницы и добавьте правильную функцию соответственно.
  • Удалите глобальный флаг из регулярного выражения, если он вам не нужен
  • Удалите регулярные выражения, если это возможно, если каждая дата всегда начинается с "/Date (", найдите его. Это гораздо быстрее (см. тест на jsperf.com )
  • todo: проверить, можно ли заменить parseInt другим методом, чтобы избавиться от конечного )/.
  • Если AjaxPro.enableDateParsing является константой, вы можете удалить if из AjaxPro.jsonParse и сделать из него условие, подобное проверке для собственного кода JSON

без RE:

if (typeof JSON !== 'undefined' && typeof JSON.parse !== 'undefined') {
    AjaxPro.nativeJsonDateParseRegex = /\/Date\(.*?\)\//g;
    AjaxPro.dateFunc = function(key, value) {
       if (typeof value === "string" && !value.indexOf("/Date(")) {
           return new Date(value.substring(6, value.length-2));
       }
       return value;
    };
    AjaxPro.jsonParse = function(text) {
        if (AjaxPro.enableDateParsing) {
            return JSON.parse(text, AjaxPro.dateFunc);
        }
        return JSON.parse(text);
    };
} else // revert to eval for ie6/ie7

Это должно быть в высокой степени оптимизировано. Возможно, вы захотите запустить еще несколько тестов самостоятельно в нескольких браузерах. Возможно, проверка свойства строки выполняется быстрее, чем проверка ее типа (сомневайтесь в этом), tвот так.

1 голос
/ 23 марта 2011

Одна не очень хорошая микрооптимизация, но все же стоит попробовать.Поскольку ваша подстрока содержит только миллисекундную метку времени, и никакой другой строки мусора. Вы можете удалить вызов parseInt .Вы можете попробовать преобразование типов с помощью простой математической операции, такой как умножение на 1 .Может сэкономить время, если вы слишком увлечены микрооптимизацией.

 value = new Date(1*(value.substr(6)));

пример:

a = "a:3333";
b = a.substring(2);
alert(b*2); // alerts 6666
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...