如何加快 JSON 日期解析速度?

发布于 2024-10-25 09:03:29 字数 1014 浏览 2 评论 0原文

我在这个项目中一直使用大约 5 年前的 AJAX 库,并且它在解析 JSON 中的日期时遇到了一些问题。我最终重写了它的解析函数以使用单个正则表达式:

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

这非常有效,但我认为如果我在 IE8 / chrome / ff 中使用本机 JSON 解析,我可以加快速度,所以我添加了这一点:

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.237ms)。关于如何使其更快的任何想法,或者这是您在不进行认真调整的情况下可以做的最好的事情吗?

I am stuck using an AJAX library from about 5 years ago in this project, and it had some issues with parsing dates in JSON. I wound up rewriting its parse function to use a single regex:

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

This works really well, but I thought I could get a speed up if I used native JSON parsing in IE8 / chrome / ff, so I added this bit:

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

The reviver callback will execute once for each JSON property returned, so it has to be very fast. During a profile I've seen it's been called 170484 times, but still runs pretty fast (131.237ms). Any ideas on how to make it faster, or is this the best you can do without serious tweaking?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小耗子 2024-11-01 09:03:30

您的代码包含很多恒定条件,您只需检查一次是否支持本机 JSON 就可以了。

建议:

  • 在页面加载时检查本机 JSPN 支持,并相应地添加正确的功能。
  • 如果不需要,请从正则表达式中删除全局标志
  • 如果可能,请删除正则表达式,如果每个日期始终以“/Date(”开头,请搜索它。它要快得多(请参阅 jsperf.com 的基准测试)
  • todo:检查 parseInt 是否可以替换为其他方法以摆脱尾随 )/.
  • 如果 AjaxPro.enableDateParsing 是一个常量,您可以从 AjaxPro.jsonParse 中删除 if 并将其设置为一个条件,例如检查本机 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

这应该是高度优化的。您可能想在多个浏览器中自行运行更多测试。也许检查字符串的属性比检查其类型(怀疑它)更快,类似的事情。

Your code contains a lot of constant conditions, you'll be fine with checking once whether native JSON is supported or not.

Suggestions:

  • check for native JSPN support at page load, and add the right function accordingly.
  • Drop the global flag from the regex if you do not need it
  • Drop regular expressions if possible, if every date always starts with "/Date(", search for it. It's much faster (see benchmark at jsperf.com)
  • todo: check whether parseInt can be replaced with an other method to get rid of the trailing )/.
  • If AjaxPro.enableDateParsing is a constant, you can remove if from AjaxPro.jsonParse and and make it a condition like the check for native JSON

Code without 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

This should be highly optimized. You might want to run some more test on your own in multiple browsers. Maybe checking for a property of a string is faster than checking its type (doubt it), thing like that.

帅冕 2024-11-01 09:03:30

一个不太好的微优化,但仍然值得一试。
由于您的子字符串仅包含毫秒时间戳,并且没有其他垃圾字符串。
您可以删除对 parseInt 的调用
您可以尝试使用简单的数学运算进行类型转换,例如与 1 相乘
如果您太热衷于微优化,可能会节省一些时间。

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

例子:

a = "a:3333";
b = a.substring(2);
alert(b*2); // alerts 6666

One not so good microoptimization, but still worth giving a try.
Since your substring contains millisecond timestamp only, and no other garbage string.
You can remove the call to parseInt.
You can try typecasting with simple mathematical operation like multiplication with 1.
Might save some time if you are too keen on microoptimizations.

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

example:

a = "a:3333";
b = a.substring(2);
alert(b*2); // alerts 6666
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文