Friday, January 28, 2011

mXHR Playground

Recently I extended supplyJS to support streaming images. (This actually was implemented all the time, I just added the listener for the MIME types)

I guess streaming javascript & stylesheet files is not expressive as streaming images (in terms of measurable performance). So now you can test it yourself:

http://www.typeofnan.com/lab/mxhr-stream/

I'd be more than happy to get some responses from you guys. If you're in the mood, please post your Browser / version / performance to the comments!

! Important !
To make this work, I'm using base64 encoded images. The Internet Explorer does not handle base64 encoded images that well, so it might not work (properly)

Thanks.

Monday, January 24, 2011

"typeof " is fast ?

Recently, I read an article about the such called "micro optimizations". The article was about when to use typeof and when just to check against the undefined value, if you want to know whether a variable/property is undefined or not.

The conclusion was, to use typeof for any "global" variable and a direct conditional check against undefined within the scope of a function where you know the variables are at least declared. That makes sense, because if( some_undefined_variable !== undefined ) throws a reference error.

I played around with that in mind and I thought, this might be interesting for fellow Javascripters. My first testcase looked like this:

var loops = 1e6,
    foo;

console.time('typeof');
while(loops--) {
    if( typeof foo !== 'undefined' ) {}
}
console.timeEnd('typeof');

loops = 1e6;

console.time('direct');
while(loops--) {
    if( foo !== undefined) {}
}
console.timeEnd('direct');

with the result of:

typeof: 421ms
direct: 603ms

Pretty interesting. So here it looks like, typeof is faster than just comparing a variable against undefined. I couldn't really believe what I've seen here. I thought that is probably because I'm in the global context and my Javascript engine (SpiderMonkey) does some kind of wierd scope chain lookups for "undefined". Anyway, it should improve the overall performance to put that code into a function (-context), which I did:

(function() {
    var loops = 1e6,
        foo;

    console.time('typeof');
    while(loops--) {
        if( typeof foo !== 'undefined' ) {}
    }
    console.timeEnd('typeof');

    loops = 1e6;

    console.time('direct');
    while(loops--) {
        if( foo !== undefined) {}
    }
    console.timeEnd('direct');
}());

Results:

typeof: 54ms
direct: 185ms

As expected, this has a better overall performance, but still typeof is way faster than a plain conditional check vs. undefined. Well, the important thing I forgot here is to keep a local reference (some people call it: cache) for the undefined value:

(function(undef) {
    var loops = 1e6,
        foo;

    console.time('typeof');
    while(loops--) {
        if( typeof foo !== 'undefined' ) {}
    }
    console.timeEnd('typeof');

    loops = 1e6;

    console.time('direct');
    while(loops--) {
        if( foo !== undef) {}
    }
    console.timeEnd('direct');
}());

Final results:

typeof: 51ms
direct: 38ms

Yay! That's the way to go and that's why you always should try to cache objects / object propertys before accessing (if its not a problem to have a static reference).
My default Javascript opener when using jQuery looks like:

(function(win, doc, $, undef) {
    // lots of beautiful code that can access win(window), 
    // doc(document), $(jQuery) and undef(undefined)
}(this, this.document, jQuery));

However, to be honest I'm still not 100% sure why this affects the undefined value that much. Cached references are faster to access (fact), totally makes sense for objects and propertys, but the undefined value is not a property as far as I know.

update:

I was wrong. undefined really is a property in the global object (window).

'undefined' in window; // = true

This explains why the cached version of the undefined value is way faster. Thanks to Stackoverflow member CMS who pointed me on this fact here.