【问题标题】:Can you get powers of 10 faster than O(log n)?你能比 O(log n) 快 10 倍吗?
【发布时间】:2011-12-29 14:13:38
【问题描述】:

我知道在大多数情况下取幂是 O(log n) 或更糟,但我在试图理解数字如何表示自己时迷失了方向。以 JavaScript 为例,因为它有多种原生数字格式:

100000 === 1E5 && 100000 === 0303240
>>> true

在内部,它们最终不都作为二进制值存储在内存中并被操作吗?如果是这样,机器是否能够像存储八进制一样快地存储十进制和科学记数法表示?

因此,您认为+("1E" + n) 会比Math.pow(10, n) 快吗?

这个问题主要是关于 1E(n) 是如何工作的,但在尝试自己思考答案时,我对如何首先解析和存储数字变得更加好奇。如果您能提供任何解释,我将不胜感激。

【问题讨论】:

    标签: javascript algorithm numbers exponent


    【解决方案1】:

    我不认为字符串操作会更快,因为至少连接会创建一个新对象(内存分配,GC 的更多工作),Math.pow 通常涉及单个机器指令。

    此外,一些现代 JS VM 会进行热点优化,从 javascript 生成机器代码。 Math.pow 有机会,但字符串魔法几乎不可能。

    如果您 100% 确定 Math.pow 在您的应用程序中运行缓慢(我简直不敢相信),您可以使用数组查找,它应该运行得最快:[1,10,100,1000,10000,...][n]。数组会比较小,复杂度是O(1)

    【讨论】:

    • 喜欢阵列范围。 [10^1, 10^2, ...](我知道 ^ 在 JS 中不是 pow)
    • @TomRoggero 更好[1e0, 1e1, 1e2, 1e3, ...]
    【解决方案2】:

    但我在试图理解数字如何表示自己时迷失了方向。以 JavaScript 为例,因为它有多种原生数字格式:

    在内部,它们最终不都以二进制值的形式存储和操作存储在内存中吗?

    是的,在 javascript 中,因此只有一个数字类型是 64 位浮点类型

    1 === 1.0 
    

    http://www.hunlock.com/blogs/The_Complete_Javascript_Number_Reference

    如果是这样,机器存储十进制和科学记数法表示的速度是否与存储八进制一样快?

    再次是的,因为只有一种类型。 (也许有细微差别,但应该可以忽略不计)

    但是,对于这种特定情况,可以表示的数字有一个限制 ~ 1e300,因此运行时间是 O(~300) = O(1),所有其他数字都表示为 +/- Infinity。

    因此,您认为 +("1E" + n) 会比 Math.pow(10, n) 快吗?

    不完全是! 1E100 比 Math.pow(10,n) 快 但是 +("1E"+n) 比 Math.pow(10,n); 慢 不是因为字符串和内存分配,而是因为JS解释器必须解析字符串并将其转换为数字,这比原生的 Math.pow(num,num) 操作要慢。

    jsperf test

    【讨论】:

    • 感谢您精心布置、得到充分支持的答案。
    【解决方案3】:

    我在选项上运行了jsperf

    var sum = 0;
    for (var i = 1; i < 20; ++i){
      sum += +("1E" + i);
    }
    

    因为字符串连接很慢。

    var sum = 0;
    for (var i = 0; i < 20; ++i){
      Math.pow(10, i);
    }
    

    因此速度更快,因为它只对数字进行运算。

    var sum = 0;
    sum += 1e0;
    sum += 1e1;
    ...
    sum += 1e19;
    

    最快,但只有在1ex 是预先计算的值之后才有可能。

    为了获得最佳性能,您可能需要自己预先计算答案。

    【讨论】:

      【解决方案4】:

      Math.pow 不区分数字,因此它对每个数字都一样慢,前提是解释器不针对整数进行优化。它可能只分配几个浮点数来运行。我忽略了解析时间。

      "1E"+n 将分配 2~3 个可能具有相当大内存开销的字符串对象,销毁中间体,并将其重新解析为数字。不太可能比 pow 更快。我再次忽略了解析时间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-25
        • 2022-07-22
        • 1970-01-01
        • 2011-12-12
        • 1970-01-01
        • 2020-01-15
        • 1970-01-01
        相关资源
        最近更新 更多