52

What's the fastest way to square a number in 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. 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).

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
KJ6BWB
  • 751
  • 2
  • 6
  • 10
  • 9
    http://jsperf.com/ – Brad Oct 27 '14 at 17:31
  • 1
    Test it in the implements you care about to find out and then if/when you get different results, make a decision based on which implementation you wish to favor. And don't forget to retest every time an implementation is updated. –  Oct 27 '14 at 17:32
  • You seriously mean that nobody has ever tried this and posted the results somewhere? That's what it looked like when I was using Google to try and find an answer, but I couldn't believe nobody had ever done it before. – KJ6BWB Oct 27 '14 at 17:34
  • 1
    Not to mention, why would anyone think that a call to a general function would be faster than a direct multiply operation? If you're worrying about the speed of basic arithmetic operators, you're almost certainly focusing on the wrong place for optimizations - especially if you haven't done measurements. – Michael Burr Oct 27 '14 at 17:40
  • 1
    Yeah, it's been tested before. In fact a jsperf is the first result of a [Google search](https://www.google.com/search?q=math.pow+vs.+multiplacation+javascript&rlz=1C1CHFX_enUS515US515&oq=math.pow+vs.+multiplacation+javascript&aqs=chrome..69i57j0.11968j0j7&sourceid=chrome&es_sm=0&ie=UTF-8#q=math.pow+vs.+multiplication+javascript). Some basic research on your own before posting here is recommended. – jfriend00 Oct 27 '14 at 17:42
  • Looks like squaring is faster, @MichaelBurr, and people have tried it before. I posted a link in the question. Feel free to vote for this question to be closed as a duplicate -- I can't do that, I just get downvoted when I ask an honest question that looks like it hasn't been asked before. – KJ6BWB Oct 27 '14 at 17:43
  • What terms did you search for, @jfriend00? – KJ6BWB Oct 27 '14 at 17:44
  • Click on the google search link I provided and the google search query shows right there in the Google page. – jfriend00 Oct 27 '14 at 17:45
  • You can delete your own question if you want to stop receiving down votes. – jfriend00 Oct 27 '14 at 17:46
  • 1
    How is that other question relevant? It's asking something entirely different. As to your question, there's no right answer. It depends on the implementations at the time that you test it. –  Oct 27 '14 at 17:47
  • I must say, I'm a little surprised that the results for direct multiply aren't far better in the [jperf benchmarks](http://jsperf.com/math-pow-vs-simple-multiplication) that @jfriend00 linked to. Then again, I think that the benchmark timings might be skewed by as much or more work being done in the looping than the squaring. – Michael Burr Oct 27 '14 at 17:47
  • @squint Because the answer to this question is found in the answers to that question. And there is a right answer, Math.pow is faster, for squaring a number at least. It's 1.5 to 2 times faster. See the 6th answer on that question I linked to. – KJ6BWB Oct 27 '14 at 17:50
  • @BartHumphries: That other question is asking why there's a performance difference between squaring and multiplying two different numbers. You're asking about two different approaches to squaring. –  Oct 27 '14 at 17:52
  • 1
    @squint, yes, two different approaches to squaring, one of which is multiplying the number by itself. I asked "is one way faster" the other question presumed that one way is faster and asked "why is one way faster". – KJ6BWB Oct 27 '14 at 17:53
  • Wow. No the other question compares squaring to an operation that has nothing to do with squaring. Yours is asking about two different approaches to squaring within a specific language. That other question has no bearing on JavaScript implementations' approaches to the problem of squaring a number. –  Oct 27 '14 at 17:55
  • @squint You don't think that when JavaScript sees "n * n" it's the same as "n * x" but that Math.pow(number,2) is optimized for squaring? Otherwise, it would have to check to see whether "n == x" which would seem to destroy the slight increase in speed from squaring in the manner listed in that other question. – KJ6BWB Oct 27 '14 at 18:01
  • 1
    You have to go to the last revision of that jsperf to find the most direct test of what you asked: http://jsperf.com/math-pow-vs-simple-multiplication/10. There, multiplying is significantly faster in Chrome, but not in Firefox. – jfriend00 Oct 27 '14 at 18:03
  • If `Math.pow()` is optimized for squaring, then don't you think that when JavaScript sees `n * n`, it would substitute `Math.pow()`? But then you're introducing a function call, which will slow it down. So if there's some optimization for squaring, there's no reason why both `n * n` and `Math.pow(n, 2)` couldn't be optimized to use it. Right? So then it depends on what optimizations the particular implementation included. To find out, you'd need to read the source code *(if it's open source)*, or just do some testing. –  Oct 27 '14 at 18:05
  • No, I don't think JavaScript would substitute that, @squint. The jsperf that jfriend00 linked to seems to indicate that doesn't happen. When the code is compiled in something like Chrome's V8, a function call is cheap -- it's basically just the next line of code. – KJ6BWB Oct 27 '14 at 18:17
  • BartHumphries: The jsperf that @jfriend00 posted suggests that the function call is *not* inlined. *Longer bars means faster.* You're saying that JS would need to test at runtime if `x == x`, but look at your function. You don't think it could make the determination that `number === number` at compile time? By far the most expensive part of the operation is going to be the function call, so it makes sense to eliminate it when possible in both cases. –  Oct 27 '14 at 18:21
  • ...and his jsperf underscores the point that you seem to be trying so hard to avoid, which is to *test it* because these things can vary in different implementations and at different times. –  Oct 27 '14 at 18:24
  • 1
    I don't get why so many downvotes? Many times the "obvious" is not obvious at all! – Rodrigo Dec 02 '16 at 02:46
  • The question about squaring being faster is about arbitrary-length binary integers. That has nothing to do with Javascript primitive operators. Javascript numbers are fixed-width double-precision floating-point. (And CPU FP and integer multiply hardware instructions are not even data-dependent: it always takes the same amount of cycles to do a multiply, regardless of the data. Except for denormals...) – Peter Cordes Mar 26 '17 at 05:08
  • Then perhaps there's some extra overhead with calling Math.pow(), as is shown in the only answer to this question (so far)? – KJ6BWB Mar 28 '17 at 22:02

3 Answers3

96

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.

As of April 2020, Chrome, Edge and Firefox show less than 1% difference between all three of the above methods.

If the jsperf link is not working (it seems to be occasionally down), then you can try this perf.link test case.

Original Answer from 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:

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. In other browsers, the multiplication is significantly faster. IE is both the slowest and shows the greatest percentage difference between the two methods. Firefox is the fastest and shows the least difference between the two.

enter image description here

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • One thing to consider is that Firefox may be optimizing away the entire operation since all values are constant, the only function involved is deterministic, and the result is never used. But overall +1 –  Oct 27 '14 at 18:41
  • @squint - of course, Firefox probably is doing macro-level optimizations, but also it's multiplication is just faster. Yet another reason why one has to test rather than theorize. – jfriend00 Oct 27 '14 at 18:48
  • 4
    Ah, I just noticed that "higher is better". I thought the length of the bars corresponded with the average length of time that it took for the operation to complete. @jfriend00, I can't upvote the answer as I don't have enough rep, I can only mark this as the accepted answer. – KJ6BWB Oct 27 '14 at 18:54
  • 2
    You should also try the "**" operator – Brendon Shaw Oct 17 '18 at 18:40
  • `var r= readLine();` `var area = Math.PI * Math.pow(r); // Showing NaN ` Where as `var area = Math.PI * (r * r ) // giving the result ` can anyone explain why ? – moshiuramit May 18 '19 at 03:05
  • 1
    @moshiuramit - `Math.pow()` requires two arguments, not one. – jfriend00 May 18 '19 at 04:10
  • JSPerf seems to be down for an extended period of time. I'd post a link to an updated one on https://perf.link, but apparently SoackOverflow bans URL shorteners in comments and the URL generated by perf.link is *waaaay* too long..... – starbeamrainbowlabs Jan 25 '21 at 18:08
  • 1
    @starbeamrainbowlabs - I added a perf.link option to my answer. It appears that perf.link stores the entire test case in the link which is why it's so long which does make it unfriendly for sharing without a shortener, but I guess saves them from any test case storage. – jfriend00 Jan 25 '21 at 18:26
32

In ES6 you can do the following with Exponentiation (x ** y), which produces the same result as 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.

alert(bigInt(5).square());
<script src="https://cdnjs.cloudflare.com/ajax/libs/big-integer/1.6.40/BigInteger.min.js"></script>
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
1

In general, x * x is either much faster than or about the same as a pow() call in any language. 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. 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. This is standard advice in numerical analysis: never use pow() for x^2 (or x^.5). 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). 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. 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. 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.

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. It's not going to load x from memory and then load it from memory again, or move it from one register into another. 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. 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. Again, you can hope that it intelligently inlines pow(x,2) to x * x, but don't count on it.