【问题标题】:Is Subtracting Zero some sort of JavaScript performance trick?减零是某种 JavaScript 性能技巧吗?
【发布时间】:2019-08-08 13:24:41
【问题描述】:

查看 jQuery 核心,我发现了以下代码约定:

nth: function(elem, i, match){
    return match[3] - 0 === i;
},

我真的很好奇 sn-p match[3] - 0

在 google 上搜索“-0”并不太高效,搜索“负零”会返回对 Bob Dylan 歌曲的引用。

那么,谁能告诉我。这是某种性能技巧,还是有理由这样做而不是parseInt 或parseFloat?

【问题讨论】:

标签: javascript jquery


【解决方案1】:

可能只是将左侧强制为整数的一种简便方法。当然,不像调用函数那么清晰。

This tutorial on type-conversion 状态:

任何数学运算符,除了 连接/加法运算符将 强制类型转换。所以转换 一个字符串到一个数字可能需要 进行数学运算 的字符串表示 不会影响的号码 结果数,例如减去 零或乘以一。

这也表明“减”是比“减”更好的搜索词。 :)

【讨论】:

    【解决方案2】:

    将 JS 字符串强制转换为数字的各种方法及其后果:


    (来源:phrogz.net)

    我个人使用*1,因为它打字很短,但仍然很突出(与一元+不同),要么给我用户输入的内容,要么完全失败。我只在我知道最后会忽略非数字内容,或者当我需要解析非 base-10 字符串时使用parseInt()。

    【讨论】:

    • 谢谢。有没有关于这些相对表现的指标?
    • 我会尝试创建一些。一般来说,这些方法 (parse*) 会明显比隐式转换慢,但可能不会明显慢,除非你正在做很多字符串到数字转化。
    • @JamesWiseman 我创建了一个基准,但结果通常差异太大而无法报告。您可以在此处尝试基准测试:phrogz.net/JS/string_to_number.html 重新加载几次以查看变化。
    • 嗯,我明白了。我想知道是否可以通过对大量处决取平均值来推断出什么。
    • @JamesWiseman 欢迎您尝试。问题在于,对于今天的 JIT 解释器,执行时间可能会根据您执行某项任务的频率而有所不同。
    【解决方案3】:

    基于一些快速而肮脏的基准测试,"1234" - 0 在 Firefox 3.6 中比 parseInt("1234") 快约 50%,比 +"1234" 快​​ 10%。

    更新:

    我的“快速而肮脏”的基准测试并不是很有用,因为它只是在循环中转换字符串“1234”。我再次尝试使用随机数字列表,结果遍布地图。这三种方法在这台电脑上都在 400-500 毫秒之内,除非它们跳转到 1300 毫秒!我认为垃圾收集正在干扰。下面是一些可以在 Firebug 中使用的代码,以防我做了一些愚蠢的事情:

    function randomList() {
        var list = [];
        for (var i = 0; i < 1000000; i++) {
            list.push("" + Math.floor(Math.random()*4000000000));
        }
        return list;
    }
    
    function testParseInt(list) {
        console.log("Sanity check: parseInt('" + list[0] + "') = " + parseInt(list[0]) );
        var start = new Date();
        for (var string in list)
            var tmp = parseInt(string);
        var time = new Date() - start;
        console.log("parseInt(string): " + time);
    }
    
    function testMinusZero(list) {
        console.log("Sanity check: '" + list[0] + "' - 0 = " + (list[0] - 0));
        var start = new Date();
        for (var string in list)
            var tmp = string - 0;
        var time = new Date() - start;
        console.log("string - 0: " + time);
    }
    
    function testUnaryPlus(list) {
        console.log("Sanity check: +'" + list[0] + "' = " + (+list[0]));
        var start = new Date();
        for (var string in list)
            var tmp = +string;
        var time = new Date() - start;
        console.log("+string: " + time);
    }
    
    function testPlusZero(list) {
        console.log("Sanity check: '" + list[0] + "' + 0 = " + (list[0] + 0) + " Oh no!");
        var start = new Date();
        for (var string in list)
            var tmp = string + 0;
        var time = new Date() - start;
        console.log("string + 0: " + time);
    }
    
    
    var numbers = randomList();
    
    testParseInt(numbers);
    testMinusZero(numbers);
    testUnaryPlus(numbers);
    testPlusZero(numbers);
    

    【讨论】:

    • 感谢您不厌其烦地这样做。我想知道 +0 和 -0 之间是否有任何比较差异,正如@S.Mark 的帖子中所强调的那样。
    • 顺便说一句,我在回答中提到的一元 + 应该是 +"1234" 而不是 "1234" + 0
    • 我最喜欢的 jsperf,以各种方式测试解析/转换为数字的速度:jsperf.com/performance-of-parseint/14(注意它们在 NaN 方面有不同的结果:~~"x" = 0,而"x"-0 = NaN)
    【解决方案4】:

    只是一个信息,根据this网站

    使用一元 + 运算符比以下任何一种(包括 '- 0')都快:

    var numValue = stringValue - 0;
    /* or */
    var numValue = stringValue * 1;
    /* or */
    var numValue = stringValue / 1;
    

    一元 + 运算符也可以进行类型转换 它是一个数字的操作数,因为 它 不做任何额外的 数学运算是 类型转换的最快方法 字符串转换成数字。

    这与詹姆斯的基准相矛盾,尽管他可能是正确的。我认为如果 jQuery 很慢,它就不会使用这种语法。

    【讨论】:

    • +1。 “慢”是一个相对术语。 James 的基准测试虽然是一个很好的“快速而肮脏”的示例,但它仅基于 Firefox。不同的 JavaScript 实现在性能优化上有所不同,而其他浏览器可能并非如此(只有一种方法可以真正找出答案)。
    【解决方案5】:

    您使用此语法的主要原因是,如果您有可能是任意数字(int 或 float)的通用代码,并且您想要进行类型敏感的比较 (===)

    【讨论】:

      【解决方案6】:

      如果不是丢失的旧遗物,那么它只是尝试将类型更改为数字。

      【讨论】:

      • 我意识到它将类型更改为数字。我希望能解释为什么这样做。
      【解决方案7】:

      在我看来,它真的像一个“高性能”的 parseInt。

      【讨论】:

      • 根据我的回答,不是parseInt,而是parseFloat 没有忽略尾随垃圾"feature"。
      猜你喜欢
      • 2010-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 2018-05-26
      相关资源
      最近更新 更多