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.
Related
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'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.
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.
I think Coffeescript is an awesome language! I was looking for some projects / issues / features that add Static Analysis to Coffeescript. However after some searching I found that the Coffeescript faq and this page suggest that static analysis might not be viable.
I was wondering that if there is a fundamental issue in implementing static analysis / static type checking in Coffeescript, because of which something of this sort does not already exist in the compiler?
Also, is it something that is not possible to do for non trivial checks but might work only for straightforward analysis? When I say straightforward I mean checking for trivial stuff like, whether the user has defined a function twice by the same name (in a class) or on the top level (or perhaps on the top level in a collection of related .coffee files).
I would appreciate if anyone could please point out some examples that show why implementing static analysis / type checking is not straightforward / possible / worth spending time on?
Thank you very much!
This answer is a bit of a brain dump since I'm interested in this also. Hope it helps.
I use the Google Closure Compiler to statically analyze the code that CoffeeScript generates. It has a really good static analyzer, and I'm not sure if there's a good reason to reinvent the wheel here. The easy way is to just write the annotations by hand:
###*
* #param {number} x
* #param {number} y
* #return {number}
###
adder = (x, y) -> x + y
It's a bit verbose, but on the other hand you're borrowing the static analysis abilities of the closure compiler which is really powerful and is able to check a lot. I actually write type annotations in a slightly more concise way, then have a script to rewrite the coffee file. My code ends up looking like this:
#! {number} x {number} y #return {number}
adder = (x, y) -> x + y
I'm sure you can see that the rewriter is pretty straightforward.
A quick note before I move on. Be sure to compile your code with -b (bare) if you're running it through the closure compiler. The closure compiler is pretty good, but it's not smart enough to do data flow analysis. CoffeeScript wraps your code in an anonymous function by default, which will trip up the compiler.
Another option along the same path (this would break compatibility with CoffeeScript, but would be a lot cooler) would be to have the Coffee compiler compile something like this:
adder = (number x, number y): number -> x + y
into JS like this:
/***
* #param {number} x
* #param {number} y
* #return {number
*/
var adder = function(x, y) {
return x + y;
};
which could then be fed into the closure compiler on a compile - if there were no errors the compiler could then strip all the comments out.
Indeed, this guy appeared to be doing exactly this. Sadly, his work seems to be in an incomplete state.
In all of these cases, we defer the hard work - static typechecking - to the closure compiler. If you don't want to do this, I'd understand, but it'd be tough to convince me that it's worthwhile to build a whole new static analysis tool from scratch. :)
EDIT a year later: I just use typescript these days. :)
I'm not an expert in CoffeeScript, so this might be the completely wrong answer, but it basically boils down to this: CoffeeScript is a very expressive language, with most of the semantics dynamically determined (and possibly strange edge cases). This is in much contrast to languages like Standard ML, which have a much more strictly defined semantics. In general, doing static analysis on higher order languages is considered very hard. I.e., static analysis on real higher order programs (Haskell, ML, especially javascript because of things like eval) is just hard because the flow of control is much more flexible. In fact, the static analysis solutions for higher order languages have really only been explored within the past twenty years or so. (Notably, see Matt Might's article on a tutorial style description of CFA.)
Basically, the reasons are this:
To do analysis, you have to deal with the problem of the expressive semantics coming form the flow control you get by slamming around higher order functions.
To do typing, typically these languages have a much richer set of types that are available. For example, there are very typically situations where if you try to assign a static type to a variable in Ruby (as in C, Java, ML, etc...) you get an error, but because certain paths of your program are never executed, it's all fine. Along with that, languages like Ruby others add a plethora of implicit type conversions that are really used to do cool programming. The notable work in this area with which I'm familar (dynamic analysis of static types for Ruby) comes from some of the people I work with, but there are certainly other examples.
Basically, the language is used in a much more dynamic way, with a much more expressive semantics, and reasoning about that statically is much harder, and prone to be imprecise. The basic front of approaching this (these days) is starting to look hybrid: you can statically analyze part of a program, and than also require the programmer give some test cases to do some kind of refined analysis.
I hope this somewhat answers your questions, again, sorry I can't address directly the direct concerns of your question as it applies to CoffeeScript, but there's a lot of work going on in analyzing things like JavaScript right now. I'll note that some of the real problems with Javascript come from it's strange semantics, the prototypical inheritance is hard to reason about, and especially eval()! Typically program analyses for these languages impose certain restrictions (for example, throwing out eval completely!) to make the analysis more feasible!
Currently I'm creating an web based (= JavaScript) application thata is using a lot of "points" (= small, fixed size vectors). There are basically two obvious ways of representing them:
var pointA = [ xValue, yValue ];
and
var pointB = { x: xValue, y: yValue };
So translating my point a bit would look like:
var pointAtrans = [ pointA[0] + 3, pointA[1] + 4 ];
var pointBtrans = { x: pointB.x + 3, pointB.y + 4 };
Both are easy to handle from a programmer point of view (the object variant is a bit more readable, especially as I'm mostly dealing with 2D data, seldom with 3D and hardly with 4D - but never more. It'll allways fit into x,y,z and w)
But my question is now:
What is the most efficient way from the language perspective - theoretically and in real implementations?
What are the memory requirements?
What are the setup costs of an array vs. an object?
...
My target browsers are FireFox and the Webkit based ones (Chromium, Safari), but it wouldn't hurt to have a great (= fast) experience under IE and Opera as well...
Arrays are faster to create, but if you consider access time it's the other way around. Also note, that constructor form is fast to create and access. It has the best of both words in modern implementations new Vector(x, y) - [Test]
Browsers tested: Chrome 10, Firefox 3.6, Firefox Beta 4.0b9, IE 9 Preview 7, Opera 11
My hunch is that Arrays will give you better performance.(!)
That said, the code is already significantly less readable in your Array example than in your Object example. The gains are likely slight, so I suggest you do some basic benchmarking and back-of-the-napkin math to put a real number on the tradeoff.
For starters, you could
Start a timer
Construct 1 thousand random [X,Y] Arrays
Access their fields 1 million times.
Repeat with Objects and compare.
(!) - A good example of why benchmarking is so useful: Arrays are indeed better for creation, but Objects are better for access, which could be very important (depending on your needs). galambalazs has written a great test for this case: http://jsperf.com/object-vs-array
Thanks for all the answers and the input. Very interesting were the results of the test written by galamalazs: http://jsperf.com/object-vs-array/2
Taking all aspects together we'll get:
Arrays should be indexed by number and not by string (arr[0] vs. arr['0'])
Performance between the Object and the Array form differs mostly by implementation not by type.
There is no winner, it changes from implementation to implementation
Future implementations of the browsers known today might also change who's winning - in either way
On Chromium the Arrays will use half the memory of the Object - but we are talking about 40 MB and 80 MB for one million instances - that is 40 to 80 bytes each.
The memory consumption of other JavaScript implementations is not known - but it'll most probably also differ as much as the performance.
So in the end both options are sensible and only the code readability will make the decision!
If it's mostly for storing data with trivial work (like in my current project) the Object way is the way to go. An mouse.x and mouse.y trivially shows the developer intend.
In mostly mathematically oriented applications with vector maths like coordinate transformations (especially going to 3D) the best way would be the Array case as things like matrix multiplications would look more native to the developer and show his intent.