What's the fastest way to square a number in JavaScript? - javascript

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).

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.

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>

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.

Related

Different results of Math.hypot() on Chrome and Firefox

When I run the simple calculation below the results on Chrome and Firefox slightly differ.
Chrome: 56.1124478168614
Firefox: 56.11244781686139
let x = -24.42;
let y = -50.519999999999925;
console.log(Math.hypot(x, y));
Is there a hole in the specification of Math.hypot() or is one of the browsers implementing it in a wrong way?
Edit: In Firefox Math.hypot(x, y) gives the same result as Math.sqrt(x*x, y*y), in Chrome the result from Math.hypot(x, y) is slightly different. Therefore I suspect Firefox is doing the calculation correctly.
Although Math.js is the same code in both browsers, different engines have different algorithms for performing basic arithmetic. For example, there are many different methods of computing a square root, and it is unlikely that two different engines would share the exact same implementation.
There are efforts to standardise precision across engines, yet they are as of yet unsuccessful. See this article for example.
As to why Math.hypot in Chrome would return a different value to doing the calculation manually in the same engine, Math.hypot is intended as an efficient approximation - not just a neat way of wrapping up the work into a single function. Thus, depending on the implementation, its results may differ from the actual calculation. You are right in stating that in this case, Firefox has the more numerically accurate implementation, as evidenced by your simple test.
In Firefox Math.hypot(x, y) gives the same result as Math.sqrt(x*x, y*y)
That lets us make a fairly confident guess for how Firefox implemented Math.hypot :-)
in Chrome the result from Math.hypot(x, y) is slightly different
Here is Chrome's implementation:
https://chromium.googlesource.com/v8/v8/+/master/src/builtins/math.tq#389
As you can see from the comment in line 421, a Kahan summation is used to avoid/minimize rounding errors -- so apparently the intention was to be more accurate than a simple sqrt(x*x + y*y) implementation. (I've tried to verify whether that's actually the outcome in this case, but Wolfram Alpha just rounds to 56.1124, and I don't know of another convenient infinite-precision floating-point evaluator out there, so I can't say for sure.)
doing the calculation correctly
In the presence of limited precision and rounding errors, the "correct" way is hard to define. For example, there are situations where the (mathematically equivalent!) expressions (a * b) / c and a * (b / c) produce different results due to rounding, and what's more, where the values of a, b, c determine which way of computing the result gets closer to the (unlimited-precision) theoretical result, so each implementation could get "lucky" or "unlucky".

Options to speed up Math.pow() in JavaScript?

I have some code which requires many Math.pow() function calls per second. In testing it seems to be a very large bottleneck to the performance of the code.
The results don't need to be precise - an accuracy of anywhere upwards of 85% should done fine - but my question would be is there any way I can somehow speed these calculations up? Maybe at the cost of some precision?
Edit: these calculations are very unlikely to repeat so a cache wouldn't work.
at the cost of some precision
How much loss of precision? If you only need correct answers by a factor of 2, you could use bitwise manipulation.
function pow2(n) {
return 2 << (n-1);
}
console.log(pow2(n) === Math.pow(2, n));
The Number constructor (including number literals) use only floating point numbers. This function converts the floats to 32-bit integers as described here.
Otherwise, I doubt you'll be able to beat the optimized native implementation of Math.pow.
jsPerf is a great tool for trying multiple techniques to find the fastest one.
This could vary quite a bit by browser or operating system, but so far it turns out that Math.pow is much faster in my environment (Chrome 42, 64-bit Linux) until you open up dev tools. With dev tools open, it's slightly faster to multiply the number as many times as you need depending on the power, as in the following example:
function pow(num, pow) {
var result = num;
while (--pow) {
result *= num;
}
return result;
}
I'm running out of different ideas, but you can see what I have so far here:
http://jsperf.com/math-pow-alternatives
There is also a lot of overhead just to calling a function (hundreds of thousands of times). In this case it seems like Math.pow is the way to go, but there might be other ways to improve performance (or at least perceptible performance). If the code is blocking and the browser is experiencing some lag, you might try using web workers, or limiting the number of calculations per frame. You could also try to reduce the amount of function calls, or make sure you're interacting very minimally with the DOM (especially during the calculations, but preferably not at all).
Without a more concise code sample it will be difficult to fine-tune your code's performance.

In Javascript, which operator is faster, the '*' multiply or '/' divide?

In javascript, is there a speed advantage between the multiplication operator and the division operator? As an example...
var foo = bar * 0.01;
var foo = bar / 100;
foo is the same for both, but which statement returns the value of foo the fastest? I know this may be an incredibly small difference, however, when loop processing large amounts of data it could make a bigger difference than realized, which would then make a difference in how I construct equations to facilitate the processing.
I would say, it depends on the implementation. I would just make an own test somehow or try to google it.
For most machines, multiplications is faster, but the raw CPU speed is not decisive when it comes to scripting languages. Even when the implementation is the same, the execution time for one or the other will not differ so much, since the overhead of scripting languages is normally much bigger.
Normally the difference between different operations is so small, that it is not worth it to think about it. When you must, you probably are using the wrong language, anyhow.
In computer systems, the only basic operators are + (adders) and (*) multipliers. You either add (negative or positive) numbers or rotate numbers (either left or right for multiplication and division respectively). You should be able to work it out whether multiplication or division takes longer...
*btw...unless I am wrong, your question has nothing to do with javascript. Javascript is an interpreted language with engines such as spidermonkey or rhino....
FYI You should read this - directly from the main people....to have better insight of "what" might be happening.

What comparison operators are more processor efficient: <, <=, != or ==?

I have the choice between types of comparison operations, please put them in the order of efficiency for the processor starting with the most efficient:
if (x == 1)
if (x != 0)
if (x < 2)
if (x <= 3)
Often I am faced with case where I can use any of them I choose for the same outcome...
This is something I've always wanted to know and probably some other people want to know it too. Also, does it vary for different programming languages or not?
Edit: Thanks for the information. Because they are apparently all the same efficiency this means I can use more > or < type operators in order to catch glitches better!
Usually, any of them is more efficient than the others. This is because on most CPUs, they map to specialized opcodes, whose execution is handled by the very same physical unit, in slightly different configurations. Using a non-existent but very simple to understand assembly syntax, each branch (if condition) might translate to:
if (x == 1)
test = x - 1
branch_equal_zero test
if (x != 0)
test = 0
branch_non_equal_zero test
if (x < 2)
test = x - 2
branch_lower_than_zero test
if (x <= 3)
test = x - 3
branch_lower_or_equal_to_zero test
As you can see, comparing to zero (regardless of the comparision) might be faster because there is no subtraction involved -- but faster of such a tiny fraction of second you might notice it only under extremely heavy load.
Even if we are speaking of interpreted languages (PHP and JS), the answer does not change, because all operators are directly mapped to the underlying native comparisions by the interpreters. Let alone any type cast or intermediate conversion that might take place.
The simple answer is "They are all the same", because, at the basic level, they are all the same. Also, they are all so blazingly fast, you won't notice the difference anyway.
I can see how one may be quicker than the other - CPUs tend to reorder instructions and predict branches - so in specific cases there may be a difference.
However, none if these cases applies to anything you do in JavaScript. In JavaScript you can be very certain they are all the same.
Let's put it differently, starting from the higher level.
Javascript and PHP, both of them are high level language, and so won't use CPU directly but over many processes already thought to optimize what you write. In Javascript that "process" is called Javascript Engine. In PHP it is the interpreter itself. Don't misunderstand me, they are thought to do their work leaving "a bit" of care on optimization.
So in the end the real way to optimize this kind of operation would be to find a real big issue in PHP or Javascript Engine itself.
Now let's face the lowest aspect of these operators. A modern CPU has 3.2GHz (or even more) clock speed. So, it would mean 3200000000 operations per second, which is a huge number. Suppose those operation (which in the end are almost all the same) use 2 or 3 ticks. it would take you about 10^9 operators to notice a significative difference.

Speed of the Math Object in Javascript

I'm working on a javascript application that makes intensive use of math operations, dozens of calls per mouse move. I've been working on others' people code as a starting point, and I often find work arounds for the native javascript Math, such as...
var pi = Math.PI
var distance = (x * x) + (y * y) / R * R
var pixels = ~~(x/y)
Is there a significant performance hit for using the Math object? If so, what are some common workarounds?
If you are for some reason doing computing intensive stuff in javascript, you must remember those things (*and read David Mandelin's Know Your Engines: How to Make Your JavaScript Fast presentation - PDF, where he describes this in more details*):
inline everything you can.
function calls are very expensive
object access is expensive
polymorphism can cost you performance, your variables and arguments should always hold only one data type.
Math object is not especially slow, but you will not find distance() function there anyway, and accessing its methods from closure via Math.method() calls is, inefficient.
so sqrt is, of course, worse than x*x, custom random function might be better for you, Pi should be cached in loops, min and max should probably be avoided as well, no idea about trigonometry and logarithms speed.
P.S.: You can do things like ((x >= 0 ? x : -x) + 0.5) >> 0, to replace Math.ceil(Math.abs()), but remember - when i say "intensive" - i'm talking about number crunching, data processing, physics, graphics and things like that. For normal JavaScript sites or RIAs - you should not do stuff i am suggesting here. Also, most of the speed hacks have their side effects
I do not agree on the function calls. if statements inside if statements and long specialised functions is slower than well organised code with many small generalised functions.

Categories

Resources