简体   繁体   English

在 JavaScript 中平方一个数字的最快方法是什么?

[英]What's the fastest way to square a number in JavaScript?

What's the fastest way to square a number in JavaScript?在 JavaScript 中平方一个数字的最快方法是什么?

function squareIt(number) {
   return Math.pow(number,2);
}

function squareIt(number) {
   return number * number;
}

Or some other method that I don't know about.或者其他一些我不知道的方法。 I'm not looking for a golfed answer, but the answer that's likely to be shortest in the compiler, on the average.我不是在寻找一个完美的答案,而是平均而言在编译器中可能最短的答案。

Edit: I saw Why is squaring a number faster than multiplying two random numbers?编辑:我看到了为什么对一个数字进行平方比将两个随机数相乘要快? which seemed to indicate that squaring is faster than multiplying two random numbers, and presumed that n*n wouldn't take advantage of this but that Math.pow(n,2) would.这似乎表明平方比将两个随机数相乘要快,并假设 n*n 不会利用这一点,但 Math.pow(n,2) 会。 As jfriend00 pointed out in the comments, and then later in an answer, http://jsperf.com/math-pow-vs-simple-multiplication/10 seems to suggest that straight multiplication is faster in everything but Firefox (where both ways are similarly fast).正如 jfriend00 在评论中指出的那样,然后在回答中指出, http: //jsperf.com/math-pow-vs-simple-multiplication/10 似乎表明直接乘法在除 Firefox 之外的所有东西中都更快(两种方式同样快)。

Note: Questions like this change over time as browser engines change how their optimizations work.注意:随着浏览器引擎改变其优化工作方式,此类问题会随着时间而改变。 For a recent look comparing:对于最近的比较:

Math.pow(x1, 2)
x1 * x1
x1 ** 2                  // ES6 syntax

See this revised performance test and run it in the browsers you care about: https://jsperf.com/math-pow-vs-simple-multiplication/32 .查看此修订后的性能测试并在您关心的浏览器中运行它: https : //jsperf.com/math-pow-vs-simple-multiplication/32

As of April 2020, Chrome, Edge and Firefox show less than 1% difference between all three of the above methods.截至 2020 年 4 月,Chrome、Edge 和 Firefox 在上述所有三种方法之间的差异均不到 1%。

If the jsperf link is not working (it seems to be occasionally down), then you can try this perf.link test case .如果 jsperf 链接不起作用(似乎偶尔会宕机),那么您可以尝试这个perf.link 测试用例

Original Answer from 2014: 2014 年的原始答案:

All performance questions should be answered by measurement because specifics of the browser implementation and the particular scenario you care about are often what determine the outcome (thus a theoretical discussion is not always right).所有性能问题都应该通过测量来回答,因为浏览器实现的细节和您关心的特定场景通常决定了结果(因此理论讨论并不总是正确的)。

In this case, performance varies greatly by browser implementation.在这种情况下,浏览器实现的性能差异很大。 Here are are results from a number of different browsers in this jsperf test: http://jsperf.com/math-pow-vs-simple-multiplication/10 which compares:以下是此 jsperf 测试中许多不同浏览器的结果: http ://jsperf.com/math-pow-vs-simple-multiplication/10 比较:

Math.pow(x1, 2)
x1 * x1

Longer bars are faster (greater ops/sec).更长的条形更快(更大的操作数/秒)。 You can see that Firefox optimizes both operations to be pretty much the same.您可以看到 Firefox 优化了这两种操作,使其几乎相同。 In other browsers, the multiplication is significantly faster.在其他浏览器中,乘法要快得多。 IE is both the slowest and shows the greatest percentage difference between the two methods. IE 是最慢的,并且显示出两种方法之间的最大百分比差异。 Firefox is the fastest and shows the least difference between the two. Firefox 是最快的,两者之间的差异最小。

在此处输入图片说明

In ES6 you can do the following with Exponentiatio n ( x ** y ), which produces the same result as Math.pow(x,y) :ES6 中,您可以使用指数n ( x ** y ) 执行以下操作,这会产生与Math.pow(x,y)相同的结果:

 function squareIt(number) { return number ** 2; } console.log(squareIt(5));

or you can use a JavaScript library called BigInteger.js for the purpose.或者你可以使用一个名为BigInteger.js的 JavaScript 库来达到这个目的。

 alert(bigInt(5).square());
 <script src="https://cdnjs.cloudflare.com/ajax/libs/big-integer/1.6.40/BigInteger.min.js"></script>

In general, x * x is either much faster than or about the same as a pow() call in any language.通常, x * x 比任何语言中的 pow() 调用快得多或大致相同。 pow() is a general exponential designed to work with floating point arguments, and it usually uses a calculation that has a lot more operations than a single multiplication. pow() 是一个设计用于处理浮点参数的通用指数,它通常使用比单个乘法具有更多运算的计算。 It's notoriously slow.这是出了名的慢。 Some pow() implementations will helpfully filter out integer powers for special evaluations, like for x^4 it might do x2=x * x, x4=x2 * x2, but adding special conditions like that can slow down the general implementation, and the x * x vs. pow() rule is so well known among programmers you can't really count on the library implementation to help you out.一些 pow() 实现将有助于过滤掉特殊计算的整数幂,例如对于 x^4,它可能会执行 x2=x * x, x4=x2 * x2,但是添加这样的特殊条件会减慢一般实现的速度,并且x * x vs. pow() 规则在程序员中是众所周知的,你不能真正指望库实现来帮助你。 This is standard advice in numerical analysis: never use pow() for x^2 (or x^.5).这是数值分析中的标准建议:永远不要对 x^2(或 x^.5)使用 pow()。 At best, it's no slower than the pow implementation, if it's optimized out as x * x at compile time, and at worst, it's horribly slower (and probably not as accurate either).充其量,它并不比 pow 实现慢,如果它在编译时优化为 x * x ,最糟糕的是,它会慢得多(而且可能也不那么准确)。 You could go and test it on every possible platform you expect your code to run on, but in real life, there's no good reason to use pow() for squares.您可以在您希望代码运行的每个可能的平台上对其进行测试,但在现实生活中,没有充分的理由将 pow() 用于正方形。 There can be good reasons to write a convenience function that does x * x, but if the language allows it, it's a good idea to make sure that it's marked up so that there's no actual function call going on at the machine level.编写一个执行 x * x 的便利函数可能有很好的理由,但如果语言允许,最好确保它被标记,以便在机器级别没有实际的函数调用。 Unfortunately, I don't think Javascript has anything like that, but I suspect that the JIT compilers are usually smart enough to render short functions like that without a jump.不幸的是,我不认为 Javascript 有这样的东西,但我怀疑 JIT 编译器通常足够聪明,可以在不跳转的情况下呈现这样的短函数。

Regarding the issue of x * x vs. x * y, the former would often be faster simply because it avoids a MOV at the machine level (aside from the considerations in the post you referenced), but it's pretty certain that the JS engine is smart enough not to do an extra MOV if the operand is already in a register.关于 x * x 与 x * y 的问题,前者通常会更快,因为它避免了机器级别的 MOV(除了您引用的帖子中的考虑因素),但可以肯定的是 JS 引擎是如果操作数已经在寄存器中,则足够聪明,不会执行额外的 MOV。 It's not going to load x from memory and then load it from memory again, or move it from one register into another.它不会从内存加载 x 然后再次从内存加载它,或者将它从一个寄存器移到另一个寄存器。 That's a basic behavior of optimizing compilers.这是优化编译器的基本行为。 You have to keep in mind that the compiler is going to do a lot of rearranging and consolidation of algebraic operations, so when you write x * x, a lot of things could be going on depending on what happened to x previously or happens to it later.你必须记住,编译器会对代数运算进行大量的重新排列和合并,所以当你写 x * x 时,很多事情可能会发生,这取决于 x 之前发生了什么或发生在它身上之后。 This is another reason to avoid pow(), since the optimizer can do a lot of tricks with x * x that may not be available if it does a pow() call instead.这是避免 pow() 的另一个原因,因为优化器可以对 x * x 执行很多技巧,如果它改为执行 pow() 调用,则这些技巧可能不可用。 Again, you can hope that it intelligently inlines pow(x,2) to x * x, but don't count on it.同样,您可以希望它智能地将 pow(x,2) 内联到 x * x,但不要指望它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 JavaScript 中将字符串转换为数字的最快方法是什么? - What's the fastest way to convert String to Number in JavaScript? JavaScript 中测试给定参数是否为平方数的最佳方法是什么? - What's the best way in JavaScript to test if a given parameter is a square number? 调用 javascript function 的最快方法是什么 - What's the fastest way to call a javascript function 在Javascript中迭代对象属性的最快方法是什么? - What's the fastest way to iterate over an object's properties in Javascript? 在 JavaScript 中计算字符串中行数的最快方法是什么? - What is the fastest way to count the number of lines in a string in JavaScript? 查找启动字符串的制表符数量的最佳/最快方法是什么? - What's the best/fastest way to find the number of tabs to start a string? 在javascript中保存有序地图的最快方法是什么? - What's the fastest way to keep an ordered map in javascript? 在javascript中隐藏和显示表格的所有行的最快方法是什么? - What's the fastest way of hiding and showing all the rows of a table in javascript? 在 JavaScript 中遍历数组的最快方法是什么? - What's the fastest way to loop through an array in JavaScript? 在 JavaScript 中将数字转换为基数 64 的最快方法? - Fastest way to convert a number to radix 64 in JavaScript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM