我知道在大多数情况下取幂是O(log n)或更差,但是我试图理解数字是如何表示的,我迷路了。以JavaScript为例,因为它有几种原生数字格式:
100000 === 1E5 && 100000 === 0303240
>>> true
在内部,他们最终都不会被存储和操作为存储在内存中的二进制值?如果是这样,机器能够像八进制一样快地存储小数和科学表示法吗?
因此,您希望+("1E" + n)
比Math.pow(10, n)
更快吗?
大多数情况下,这个问题是关于1E(n)是如何工作的,但是在尝试自己思考答案时,我更加好奇这个数字是如何被解析和存储的。如果您能提供任何解释,我将不胜感激。
答案 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)操作慢。
答案 3 :(得分:0)
Math.pow不区分数字,因此只要解释器不优化整数,它对每个数字都是一样慢。它可能只分配几个浮点数来运行。我无视解析时间。
“1E”+ n将分配2~3个字符串对象,这些对象可能具有相当大的内存开销,破坏中间体,并将其重新分解为数字。不太可能比战斗更快。我再次无视解析时间。