I was just wondering how the overhead is on a function object.
In an OOP design model, you can spawn up a lot of objects each with their own private functions, but in the case where you have 10,000+, these private function objects, I assume, can make for a lot of overhead.
I'm wondering if there are cases where it would be advantageous enough to move these functions to a utility class or external manager to save the memory taken up by these function objects.
This is how Chrome handles functions, and other engines may do different things.
Let's look at this code:
var funcs = [];
for (var i = 0; i < 1000; i++) {
funcs.push(function f() {
return 1;
});
}
for (var i = 0; i < 1000; i++) {
funcs[0]();
}
http://jsfiddle.net/7LS6B/4/
Now, the engine creates 1000 functions.
The individual function itself takes up almost no memory at all (36 bytes in this case), since it merely holds a pointer to a so-called SharedFunctionInfo object, which is basically a reference to the function definition in your source code*. This is called lazy parsing.
Only when you run it frequently does the JIT kick in, and creates a compiled version of the function, which requires more memory. So, funcs[0] takes up 256 bytes in the end:
*) This is not exactly true. It also holds scope information and the function's name and other metadata, which is why it has a size of 592 bytes in this case.
First of all, it's common to place methods in the object constructor prototype, so they'll be shared among all instances of a given object:
function MyObject() {
....
}
MyObject.prototype.do_this = function() {
...
}
MyObject.prototype.do_that = function() {
...
}
Also note that a "function object" is a constant code-only block or a closure; in both cases the size is not related to the code:
x = [];
for (var i=0; i<1000; i++) {
x.push(function(){ ... });
}
The size of each element of the array is not going to depend on the code size, because the code itself will be shared between all of the function object instances. Some memory will be required for each of the 1000 instances, but it would be roughly the same amount required by other objects like strings or arrays and not related to how much code is present inside the function.
Things would be different if you create functions using JavaScript's eval: In that case I'd expect each function to take quite a bit and proportional to code size unless some super-smart caching and sharing is done also at this level.
Function objects do in fact take up a lot of space. Objects themselves may not take up much room as shown below but Function objects seem to take up considerably more. In order to test this, I used Function("return 2;") in order to create an array of anonymous functions.
The result was as implied by the OP. That these do in fact take up space.
Created
100,000 of these Function()'s created caused 75.4 MB to be used, from 0. I ran this test in a more controlled environment. This conversion is a little more obvious, where it indicates that each function object is going to consume 754 bytes. And these are empty. Larger function objects may surpass 1kb which will become significant very quickly. Spinning up the 75MB was non trivial on the client, and caused a near 4 second lock of the UI.
Here is the script I used to create the function objects:
fs = [];
for(var i = 0; i < 100000; i++ ){
fs.push(Function("return 2;"));
}
Calling these functions also affects memory levels. Calling the functions added an additional 34MB of memory use.
Called
This is what I used to call them:
for( var i = 0; i < fs.length; i++ ){
for( var a = 0; a < 1000; a++ ){
fs[i]();
}
}
Using jsfiddle in edit mode is hard to get accurate results, I would suggest embedding it.
Embedded jsFiddle Demo
These statements are incorrect, I left them to allow the comments to retain context.
Function objects don't take very much space at all. The operating system and memory available are going to be what decides in the end how this memory is managed. This is not going to really impact anything on a scale which you should be worried about.
When loaded on my computer, a relatively blank jsfiddle consumed 5.4MB of memory. After creating 100,000 function objects it jumped to 7.5MB. This seems to be an insignificant amount of memory per function object (the implication being 21 bytes per function object: 7.5M-5.4M / 100k).
jsFiddle Demo
Related
As in java
int requires 4 bytes
float requires 4 bytes
char requires 2 bytes
but in javascript we only have variable with type var.
Q1. How much memory var requires?
Q2. When this memory is allocated to the variable?
As in the below example different type of data is allocated to same variable
var a = 1;
console.log(a, typeof a);
a = "javascript";
console.log(a, typeof a );
How much memory var requires?
We will never know. It can range from nothing to a few bytes. That depends on the engine, and the optimization steps it takes. Take this example:
function test() {
var unused = "stuff";
}
In this case unused cannot be used, and the compiler might decide to completely optimize it away, then it takes up no memory. However if you add a breakpoint in that function, it has to fall back to an unoptimized version and has to allocate unused.
Or take this:
function addOne(n) { return n + 1; }
var test = addOne(2);
test = addOne(3);
The compiler could optimize it in a few ways:
1) It doesn't optimize anything, then n could contain any possible JavaScript value, therefore it is probably referencing some kind of "value" superclass. The reference will take up a few bytes, so does the class instance itself.
2) It assumes that n is always a number (cause it saw that from the calls), and generates optimized bytecode that only allocates a number (or an integer) onto the stack. That will take up 8 bytes (maybe less / more).
3) It completely inlines the function, n doesnt exist at all. The resulting code is:
var test = 2 + 1;
test = test + 1;
Now if you however do addOne("test") it has to either fall back to an unoptimized version, or generate a new optimized version for strings.
As that is what all (most) engines are doing, you never know how much space a variable does take, as it can change (multiple times) at runtime. It can even change depending on how you call it, wether you call eval or with somewhen, and wether you use the debugger to "look into" the functions.
For global variables (like in your case) it is probably not possible for the engine to do optimizations (as so many parts of the code can interact with it), so probably case 1 applies.
When this memory is allocated to the variable?
Either never, or when you call the function, or for the global scope: when the code gets parsed, or when the assignment gets reached.
// assuming a non optimized case:
function test() { // a reference holder for a gets allocated
let a;
a = {}; // an object gets allocated, a reference to it gets stored in the already allocated slot
}
The optimizations above are well documented for V8, which runs in Chrome and NodeJS among others.
There is a good conversation going on here that might help you out.
Storing primitive datatypes in javascript
I'm kind of curious about what the best practice is when referencing the 'global' namespace in javascript, which is merely a shortcut to the window object (or vice versia depending on how you look at it).
I want to know if:
var answer = Math.floor(value);
is better or worse than:
var answer = window.Math.floor(value);
Is one better or worse, even slightly, for performance, resource usage, or compatibility?
Does one have a slighter higher cost? (Something like an extra pointer or something)
Edit note: While I am a readability over performance nazi in most situations, in this case I am ignoring the differences in readability to focus solely on performance.
First of all, never compare things like these for performance reasons. Math.round is obviously easier on the eyes than window.Math.round, and you wouldn't see a noticeable performance increase by using one or the other. So don't obfuscate your code for very slight performance increases.
However, if you're just curious about which one is faster... I'm not sure how the global scope is looked up "under the hood", but I would guess that accessing window is just the same as accessing Math (window and Math live on the same level, as evidenced by window.window.window.Math.round working). Thus, accessing window.Math would be slower.
Also, the way variables are looked up, you would see a performance increase by doing var round = Math.round; and calling round(1.23), since all names are first looked up in the current local scope, then the scope above the current one, and so on, all the way up to the global scope. Every scope level adds a very slight overhead.
But again, don't do these optimizations unless you're sure they will make a noticeable difference. Readable, understandable code is important for it to work the way it should, now and in the future.
Here's a full profiling using Firebug:
<!DOCTYPE html>
<html>
<head>
<title>Benchmark scope lookup</title>
</head>
<body>
<script>
function bench_window_Math_round() {
for (var i = 0; i < 100000; i++) {
window.Math.round(1.23);
}
}
function bench_Math_round() {
for (var i = 0; i < 100000; i++) {
Math.round(1.23);
}
}
function bench_round() {
for (var i = 0, round = Math.round; i < 100000; i++) {
round(1.23);
}
}
console.log('Profiling will begin in 3 seconds...');
setTimeout(function () {
console.profile();
for (var i = 0; i < 10; i++) {
bench_window_Math_round();
bench_Math_round();
bench_round();
}
console.profileEnd();
}, 3000);
</script>
</body>
</html>
My results:
Time shows total for 100,000 * 10 calls, Avg/Min/Max show time for 100,000 calls.
Calls Percent Own Time Time Avg Min Max
bench_window_Math_round
10 86.36% 1114.73ms 1114.73ms 111.473ms 110.827ms 114.018ms
bench_Math_round
10 8.21% 106.04ms 106.04ms 10.604ms 10.252ms 13.446ms
bench_round
10 5.43% 70.08ms 70.08ms 7.008ms 6.884ms 7.092ms
As you can see, window.Math is a really bad idea. I guess accessing the global window object adds additional overhead. However, the difference between accessing the Math object from the global scope, and just accessing a local variable with a reference to the Math.round function isn't very great... Keep in mind that this is 100,000 calls, and the difference is only 3.6ms. Even with one million calls you'd only see a 36ms difference.
Things to think about with the above profiling code:
The functions are actually looked up from another scope, which adds overhead (barely noticable though, I tried importing the functions into the anonymous function).
The actual Math.round function adds overhead (I'm guessing about 6ms in 100,000 calls).
This can be an interest question if you want to know how the Scope Chain and the Identifier Resolution process works.
The scope chain is a list of objects that are searched when evaluating an identifier, those objects are not accessible by code, only its properties (identifiers) can be accessed.
At first, in global code, the scope chain is created and initialised to contain only the global object.
The subsequent objects in the chain are created when you enter in function execution context and by the with statement and catch clause, both also introduce objects into the chain.
For example:
// global code
var var1 = 1, var2 = 2;
(function () { // one
var var3 = 3;
(function () { // two
var var4 = 4;
with ({var5: 5}) { // three
alert(var1);
}
})();
})();
In the above code, the scope chain will contain different objects in different levels, for example, at the lowest level, within the with statement, if you use the var1 or var2 variables, the scope chain will contain 4 objects that will be needed to inspect in order to get that identifier: the one introduced by the with statement, the two functions, and finally the global object.
You also need to know that window is just a property that exists in the global object and it points to the global object itself. window is introduced by browsers, and in other environments often it isn't available.
In conclusion, when you use window, since it is just an identifier (is not a reserved word or anything like that) and it needs to pass all the resolution process in order to get the global object, window.Math needs an additional step that is made by the dot (.) property accessor.
JS performance differs widely from browser to browser.
My advice: benchmark it. Just put it in a for loop, let it run a few million times, and time it.... see what you get. Be sure to share your results!
(As you've said) Math.floor will probably just be a shortcut for window.Math (as window is a Javascript global object) in most Javascript implementations such as V8.
Spidermonkey and V8 will be so heavily optimised for common usage that it shouldn't be a concern.
For readability my preference would be to use Math.floor, the difference in speed will be so insignificant it's not worth worrying about ever. If you're doing a 100,000 floors it's probably time to switch that logic out of the client.
You may want to have a nose around the v8 source there's some interesting comments there about shaving nanoseconds off functions such as this int.Parse() one.
// Some people use parseInt instead of Math.floor. This
// optimization makes parseInt on a Smi 12 times faster (60ns
// vs 800ns). The following optimization makes parseInt on a
// non-Smi number 9 times faster (230ns vs 2070ns). Together
// they make parseInt on a string 1.4% slower (274ns vs 270ns).
As far as I understand JavaScript logic, everything you refer to as something is searched in the global variable scope. In browser implementations, the window object is the global object. Hence, when you are asking for window.Math you actually have to de-reference what window means, then get its properties and find Math there. If you simply ask for Math, the first place where it is sought, is the global object.
So, yes- calling Math.something will be faster than window.Math.something.
D. Crockeford talks about it in his lecture http://video.yahoo.com/watch/111593/1710507, as far as I recall, it's in the 3rd part of the video.
If Math.round() is being called in a local/function scope the interpreter is going to have to check first for a local var then in the global/window space. So in local scope my guess would be that window.Math.round() would be very slightly faster. This isn't assembly, or C or C++, so I wouldn't worry about which is faster for performance reasons, but if out of curiosity, sure, benchmark it.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I've been looking at the source code of my.class.js to find out what makes it so fast on Firefox. Here's the snippet of code used to create a class:
my.Class = function () {
var len = arguments.length;
var body = arguments[len - 1];
var SuperClass = len > 1 ? arguments[0] : null;
var hasImplementClasses = len > 2;
var Class, SuperClassEmpty;
if (body.constructor === Object) {
Class = function () {};
} else {
Class = body.constructor;
delete body.constructor;
}
if (SuperClass) {
SuperClassEmpty = function() {};
SuperClassEmpty.prototype = SuperClass.prototype;
Class.prototype = new SuperClassEmpty();
Class.prototype.constructor = Class;
Class.Super = SuperClass;
extend(Class, SuperClass, false);
}
if (hasImplementClasses)
for (var i = 1; i < len - 1; i++)
extend(Class.prototype, arguments[i].prototype, false);
extendClass(Class, body);
return Class;
};
The extend function is simply used to copy the properties of the second object onto the first (optionally overriding existing properties):
var extend = function (obj, extension, override) {
var prop;
if (override === false) {
for (prop in extension)
if (!(prop in obj))
obj[prop] = extension[prop];
} else {
for (prop in extension)
obj[prop] = extension[prop];
if (extension.toString !== Object.prototype.toString)
obj.toString = extension.toString;
}
};
The extendClass function copies all the static properties onto the class, as well as all the public properties onto the prototype of the class:
var extendClass = my.extendClass = function (Class, extension, override) {
if (extension.STATIC) {
extend(Class, extension.STATIC, override);
delete extension.STATIC;
}
extend(Class.prototype, extension, override);
};
This is all pretty straightforward. When you create a class, it simply returns the constructor function you provide it.
What beats my understanding however is how does creating an instance of this constructor execute faster than creating an instance of the same constructor written in Vapor.js.
This is what I'm trying to understand:
How do constructors of libraries like my.class.js create so many instances so quickly on Firefox? The constructors of the libraries are all very similar. Shouldn't the execution time also be similar?
Why does the way the class is created affect the execution speed of instantiation? Aren't definition and instantiation separate processes?
Where is my.class.js gaining this speed boost from? I don't see any part of the constructor code which should make it execute any faster. In fact traversing a long prototype chain like MyFrenchGuy.Super.prototype.setAddress.call should slow it down significantly.
Is the constructor function being JIT compiled? If so then why aren't the constructor functions of other libraries also being JIT compiled?
I don't mean to offend anyone, but this sort of thing really isn't worth the attention, IMHO. Almost any speed-difference between browsers is down to the JS engine. The V8 engine is very good at memory management, for example; especially when you compare it to IE's JScript engines of old.
Consider the following:
var closure = (function()
{
var closureVar = 'foo',
someVar = 'bar',
returnObject = {publicProp: 'foobar'};
returnObject.getClosureVar = function()
{
return closureVar;
};
return returnObject;
}());
Last time I checked, chrome actually GC'ed someVar, because it wasn't being referenced by the return value of the IIFE (referenced by closure), whereas both FF and Opera kept the entire function scope in memory.
In this snippet, it doesn't really matter, but for libs that are written using the module-pattern (AFAIK, that's pretty much all of them) that consist of thousands of lines of code, it can make a difference.
Anyway, modern JS-engines are more than just "dumb" parse-and-execute things. As you said: there's JIT compilation going on, but there's also a lot of trickery involved to optimize your code as much as possible. It could very well be that the snippet you posted is written in a way that FF's engine just loves.
It's also quite important to remember that there is some sort of speed-battle going on between Chrome and FF about who has the fastest engine. Last time I checked Mozilla's Rhino engine was said to outperform Google's V8, if that still holds true today, I can't say... Since then, both Google and Mozilla have been working on their engines...
Bottom line: speed differences between various browsers exist - nobody can deny that, but a single point of difference is insignificant: you'll never write a script that does just one thing over and over again. It's the overall performance that matters.
You have to keep in mind that JS is a tricky bugger to benchmark, too: just open your console, write some recursive function, and rung it 100 times, in FF and Chrome. compare the time it takes for each recursion, and the overall run. Then wait a couple of hours and try again... sometimes FF might come out on top, whereas other times Chrome might be faster, still. I've tried it with this function:
var bench = (function()
{
var mark = {start: [new Date()],
end: [undefined]},
i = 0,
rec = function(n)
{
return +(n === 1) || rec(n%2 ? n*3+1 : n/2);
//^^ Unmaintainable, but fun code ^^\\
};
while(i++ < 100)
{//new date at start, call recursive function, new date at end of recursion
mark.start[i] = new Date();
rec(1000);
mark.end[i] = new Date();
}
mark.end[0] = new Date();//after 100 rec calls, first element of start array vs first of end array
return mark;
}());
But now, to get back to your initial question(s):
First off: the snippet you provided doesn't quite compare to, say, jQuery's $.extend method: there's no real cloning going on, let alone deep-cloning. It doesn't check for circular references at all, which most other libs I've looked into do. checking for circular references does slow the entire process down, but it can come in handy from time to time (example 1 below). Part of the performance difference could be explained by the fact that this code simply does less, so it needs less time.
Secondly: Declaring a constructor (classes don't exist in JS) and creating an instance are, indeed, two different things (though declaring a constructor is in itself creating an instance of an object (a Function instance to be exact). The way you write your constructor can make a huge difference, as shown in example 2 below. Again, this is a generalization, and might not apply to certain use-cases on certain engines: V8, for example, tends to create a single function object for all instances, even if that function is part of the constructor - or so I'm told.
Thirdly: Traversing a long prototype-chain, as you mention is not as unusual as you might think, far from it, actually. You're constantly traversing chains of 2 or three prototypes, as shown in example 3. This shouldn't slow you down, as it's just inherent to the way JS resolves function calls or resolves expressions.
Lastly: It's probably being JIT-compiled, but saying that other libs aren't JIT-compiled just doesn't stack up. They might, then again, they might not. As I said before: different engines perform better at some tasks then other... it might be the case that FF JIT-compiles this code, and other engines don't.
The main reason I can see why other libs wouldn't be JIT-compiled are: checking for circular references, deep cloning capabilities, dependencies (ie extend method is used all over the place, for various reasons).
example 1:
var shallowCloneCircular = function(obj)
{//clone object, check for circular references
function F(){};
var clone, prop;
F.prototype = obj;
clone = new F();
for (prop in obj)
{//only copy properties, inherent to instance, rely on prototype-chain for all others
if (obj.hasOwnProperty(prop))
{//the ternary deals with circular references
clone[prop] = obj[prop] === obj ? clone : obj[prop];//if property is reference to self, make clone reference clone, not the original object!
}
}
return clone;
};
This function clones an object's first level, all objects that are being referenced by a property of the original object, will still be shared. A simple fix would be to simply call the function above recursively, but then you'll have to deal with the nasty business of circular references at all levels:
var circulars = {foo: bar};
circulars.circ1 = circulars;//simple circular reference, we can deal with this
circulars.mess = {gotcha: circulars};//circulars.mess.gotcha ==> circular reference, too
circulars.messier = {messiest: circulars.mess};//oh dear, this is hell
Of course, this isn't the most common of situations, but if you want to write your code defensively, you have to acknowledge the fact that many people write mad code all the time...
Example 2:
function CleanConstructor()
{};
CleanConstructor.prototype.method1 = function()
{
//do stuff...
};
var foo = new CleanConstructor(),
bar = new CleanConstructor);
console.log(foo === bar);//false, we have two separate instances
console.log(foo.method1 === bar.method1);//true: the function-object, referenced by method1 has only been created once.
//as opposed to:
function MessyConstructor()
{
this.method1 = function()
{//do stuff
};
}
var foo = new MessyConstructor(),
bar = new MessyConstructor();
console.log(foo === bar);//false, as before
console.log(foo.method1 === bar.method1);//false! for each instance, a new function object is constructed, too: bad performance!
In theory, declaring the first constructor is slower than the messy way: the function object, referenced by method1 is created before a single instance has been created. The second example doesn't create a method1, except for when the constructor is called. But the downsides are huge: forget the new keyword in the first example, and all you get is a return value of undefined. The second constructor creates a global function object when you omit the new keyword, and of course creates new function objects for each call. You have a constructor (and a prototype) that is, in fact, idling... Which brings us to example 3
example 3:
var foo = [];//create an array - empty
console.log(foo[123]);//logs undefined.
Ok, so what happens behind the scenes: foo references an object, instance of Array, which in turn inherits form the Object prototype (just try Object.getPrototypeOf(Array.prototype)). It stands to reason, therefore that an Array instance works in pretty much the same way as any object, so:
foo[123] ===> JS checks instance for property 123 (which is coerced to string BTW)
|| --> property not found #instance, check prototype (Array.prototype)
===========> Array.prototype.123 could not be found, check prototype
||
==========> Object.prototype.123: not found check prototype?
||
=======>prototype is null, return undefined
In other words, a chain like you describe isn't too far-fetched or uncommon. It's how JS works, so expecting that to slow things down is like expecting your brain to fry because your thinking: yes, you can get worn out by thinking too much, but just know when to take a break. Just like in the case of prototype-chains: their great, just know that they are a tad slower, yes...
I'm not entirely sure, but I do know that when programming, it is good practice to make the code as small as possible without sacrificing functionality. I like to call it minimalist code.
This can be a good reason to obfuscate code. Obfuscation shrinks the size of the file by using smaller method and variable names, making it harder to reverse-engineer, shrinking the file size, making it faster to download, as well as a potential performance boost. Google's javascript code is intensely obfuscated, and that contributes to their speed.
So in JavaScript, bigger isn't always better. When I find a way I can shrink my code, I implement it immediately, because I know it will benefit performance, even if by the smallest amount.
For example, using the var keyword in a function where the variable isn't needed outside the function helps garbage collection, which provides a very small speed boost versus keeping the variable in memory.
With a library like this this that produces "millions of operations per second" (Blaise's words), small performance boosts can add up to a noticeable/measurable difference.
So it is possible that my.class.js is "minimalist coded" or optimized in some manner. It could even be the var keywords.
I hope this helped somewhat. If it didn't help, then I wish you luck in getting a good answer.
Is there any difference between the run speeds of a constructor function when compared to an equivalent object initializer?
For example
function blueprint(var1, var2){
this.property1 = var1;
this.property2 = var2;
}
var object1 = new blueprint(value1,value2);
vs
object1 = {property1:value1, property2:value2};
If there is, is it relevant enough to be of concern when optimizing code or would file size take priority?
If there is, is it relevant enough to be of concern when optimizing code or would file size take priority?
Neither.
It's extremely rare for decisions like this to have any (positive) effect on the system performance. Even if current browsers (or whatever your execution environment) show an observable advantage one way or another, that difference is not terribly likely to persist over new releases.
"It's much easier to optimize correct code than to correct optimized code."
Write readable, maintainable code and when it is all correct, check to see whether it is objectionably slow or the files are unreasonably large and make the optimizations.
Ran in console:
function blueprint(var1, var2){
this.property1 = var1;
this.property2 = var2;
}
var start = new Date();
var stop;
var object1;
for (var i = 0; i < 1000000; i++) {
object1 = new blueprint(1,1);
}
stop = new Date();
console.log(stop - start);
Results...
Google Chrome: 2832 milliseconds
Firefox 3.6.17: 3441 milliseconds
Ran in console:
var start = new Date();
var stop;
var object1;
for (var i = 0; i < 1000000; i++) {
object1 = {
'property1': 1,
'property2': 1
};
}
stop = new Date();
console.log(stop - start);
Results...
Google Chrome: 2302 milliseconds
Firefox 3.6.17: 2285 milliseconds
Offhand, it's pretty obvious which one is faster. However, unless you are going through a significant amount of operations I think you should use whatever is more readable and not worry about it.
I think object intializer will be faster than using constructor because constructor has a function call and it has to maintain its own instance too.
As a side note, use constructor if you want to create multiple instances of similar objects other wise go for object initializer if only single object is required.
Using a constructor to create a trivial object with just value properties is counter-productive. Just creating a simple object literal from scratch each time is faster. You can always define a function if it is to be called from lots of different places. Hey you just created a basic constructor function :lol:
If your object becomes non-trivial, for example including getters, setters, or full-blown methods, then a constructor (with the javascript in a prototype to be shared) is orders of magnitude faster than creating an object from scratch. Of course you are talking about a few micro-seconds (on a typical desktop) for creating an object with a small amount of embedded javascript vs less than a microsecond for calling a constructor, so in most cases it isn't important. Creating an object with only value properties is another order of magnitude faster.
Remember also that the initial creation of the constructor is an expensive operation, which may be more important if it is only to be used a few times. In some cases the constructor can be pre-compiled, for example if it is defined in a javascript code module in a Firefox addon, and then it is a win-win.
There are also more formal methods for creating objects such as the Object.create() function. However this is complicated and cumbersome to use and doesn't appear to be well optimised in any current browser. In all the tests I've run it is desperately slow compared to other methods, but might be useful when you need advanced capabilities and aren't going to be calling it hundreds of times.
The constructor function is used for multiple entries under the same "object".
The object initializer should only be used for a limited amount of entries, for example 3.
The constructor function is faster for multiple entries while the ...
object initializer is faster for few entries, at least in theory, I have not tested the speeds because I doubt the difference is catastrophic.
I wouldn't worry about it. The overhead of the constructor is an additional function call and a few extra properties to set (like the prototype). With modern JIT engines, it should hardly matter.
Can you guys help me determine the performance difference of each of these
statements? Which one would you use?
Making a new Array using
- var new_list = new Array(); //or
- var new_list = [];
Appending element using
- push('a')
- new_list[i]; (if i know the length)
Ternary operator or if() {} else (){}
Trying to make isodd function, which is faster
(! (is_even)) or (x%2!=0)
forEach() or normal iteration
one more
a= b = 3; or b=3; a=b;
[edit: I'm making a Math Library. So any performance hacks discussions are also welcome :) ]
Thanks for your help.
I've always assumed that since (x&1) is a bitwise operation, it would be the fastest way to check for even/odd numbers, rather than checking for the remainder of the number.
Performance characteristics for all browser (especially at the level of individual library functions) can vary dramatically, so it's difficult to give meaningful really meaningful answers to these questions.
Anyhoo, just looking at the fast js engines (so Nitro, TraceMonkey, and V8)
[ ] will be faster than new Array -- new Array turns into the following logic
cons = lookup property "Array", if it can't be found, throw an exception
Check to see if cons can be used as a constructor, if not: throw an exception
thisVal = runtime creates a new object directly
res = result of calling cons passing thisVal as the value for this -- which requires logic to distinguish JS functions from standard runtime functions (assuming standard runtime functions aren't implemented in JS, which is the normal case). In this case Array is a native constructor which will create and return a new runtime array object.
if res is undefined or null then the final result is thisVal otherwise the final result is res. In the case of calling Array a new array object will be returned and thisVal will be thrown away
[ ] just tells the JS engine to directly create a new runtime array object immediately with no additional logic. This means new Array has a large amount of additional (not very cheap) logic, and performs and extra unnecessary object allocation.
newlist[newlist.length] = ... is faster (esp. if newlist is not a sparse array), but push is sufficiently common for me to expect engine developers to put quite a bit of effort into improving performance so this could change in time.
If you have a tight enough loop there may be a very slight win to the ternary operator, but arguably that's an engine flaw in the trival case of a = b ? c : d vs if (b) a = c; else a = d
Just the function call overhead alone will dwarf the cost of more or less any JS operator, at least in the sane cases (eg. you're performing arithmetic on numbers rather than objects)
The foreach syntax isn't yet standardised but its final performane will depend on a large number of details; Often JS semantics result in efficient looking statements being less efficient -- eg. for (var i in array) ... is vastly slower than for (var i = 0; i < array.length; i++) ... as the JS semantics require in enumeration to build up a list of all properties on the object (including the prototype chain), and then checking to make sure that each property is still on the object before sending it through the loop. Oh, and the properties need to be converted from integers (in the array case anyway) into strings, which costs time and memory.
I'd suggest you code a simple script like:
for(var i = 0; i < 1000; i++){
// Test your code here.
}
You can benchmark whatever you want that way, possibly adding timing functions before and after the for statement to be more accurate.
Of course you'll need to tweak the upper limit (1000 in this example) depending on the nature of your operations - some will require more iterations, others less.
Both are native constructors probably no difference.
push is faster, it maps directly to native, where as [] is evaluative
Probably not much of a difference, but technically, they don't do the same thing, so it's not apples to apples
x%2, skips the function call which is relatively slow
I've heard, though can't find the link at the moment, that iteration is faster than the foreach, which was surprising to me.
Edit: On #5, I believe the reason is related to this, in that foreach is ordered forward, which requires the incrementor to count forward, whereas for loops are ever so infinitesimally faster when they are run backward:
for(var i=a.length;i>-1;i--) {
// do whatever
}
the above is slightly faster than:
for(var i=0;i<a.length;i++) {
// do whatever
}
As other posters suggest, I think doing some rough benchmarking is your best bet... however, I'd also note that you'll probably get very different results from different browsers, since I'm sure most of the questions you're asking come down to specific internal implementation of the language constructs rather than the language itself.
This page says push is slower.
http://dev.opera.com/articles/view/efficient-javascript/?page=2