你能比O(log n)更快地获得10的幂吗?

时间:2011-12-29 14:13:38

标签: javascript algorithm numbers exponent

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

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

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

因此,您希望+("1E" + n)Math.pow(10, n)更快吗?

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

4 个答案:

答案 0 :(得分:3)

我认为字符串操作可能不会更快,因为至少连接会创建一个新对象(内存分配,更多GC工作),Math.pow通常会出现在单机操作中。

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

如果您100%确定Math.pow在您的应用程序中运行缓慢(我根本无法相信),您可以使用数组查找,它应尽可能最快地运行:[1,10,100,1000,10000,...][n]。数组相对较小,复杂度为O(1)

答案 1 :(得分:1)

我在选项上运行了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的常量才是预先计算的值。

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

答案 2 :(得分:1)

  

但是我迷失了,试图了解数字是如何表现出来的。以JavaScript为例,因为它有几种原生数字格式:

     

在内部,难道它们最终都不会被存储和操作为存储在内存中的二进制值吗?

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

1 === 1.0 

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

  

如果是这样,机器是否能够像八进制一样快地存储小数和科学表示法?

是的,因为只有一种类型。 (也许存在微小差异,但应该可以忽略不计)

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

  

因此,你会期望+(“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 :(得分:0)

Math.pow不区分数字,因此只要解释器​​不优化整数,它对每个数字都是一样慢。它可能只分配几个浮点数来运行。我无视解析时间。

“1E”+ n将分配2~3个字符串对象,这些对象可能具有相当大的内存开销,破坏中间体,并将其重新分解为数字。不太可能比战斗更快。我再次无视解析时间。