Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Wednesday, September 16, 2009

OnMouseMove Timer Granularity

A function to measure the average delay between one mouse move capture event in the window. If you move your mouse really, really fast, you'll discover the limits at which you can capture mouse events in your browser (OS + hardware should be factored into your results of course).

I get 2.17 ms on Ubuntu Jaunty (9.0.4) with Firefox 3.5.2.
I get 2.37 ms on Ubuntu Jaunty (9.0.4) with Opera 10.


(function(){

var bufferLimit = 1000;
var buffer = [];
var moved = function(){
buffer[ buffer.length ] = new Date().getTime();
buffer.length > bufferLimit ? (function(){
//document.removeEventListener( 'mousemove', moved, false );
//console.log( buffer );

var diff = 0;
var len = buffer.length - 1;

for( var i = 0; i < len; i++ ){
diff += buffer[ i+1 ] - buffer[ i ];
}

var meanAvg = diff / len;

document.getElementsByTagName( 'body')[ 0 ].innerHTML += 'Captured "onmousemove": ' + bufferLimit + ' times. Average delay between events: ' + meanAvg + ' ms.
';

buffer.length = 0;

})() : 0 ;
}
document.addEventListener( 'mousemove', moved, false );

})();

Wednesday, August 12, 2009

Would the Real Prototype Please Stand Up?

There are a ton of examples out there of how to Prototype with Javascript. The examples I have seen appear too complex, verbose or just plain wrong. I started OO in Java and found the switch to Javascript incredibly difficult because of some bad descriptions of what was a Prototype was actually used for.

Constructors
Prototypes are NOT blueprints of an object. They are just links to objects you want to inherit member variables from. But it is not any use knowing what a Prototype is, unless you first know what a Constructor is. So lets jump right in and define a Constructor.


// A constructor
God = function God(){
this.myName = 'YHWH';
this.thinks = true;
}

A Constructor is simply a function. The Constructor function has member variables. In this case the member variables are 'myName' and 'thinks'. Using 'new' Now we are able to make copies of Gods.
// Create some Gods
Father = new God;
Son = new God;
Spirit = new God;

Thus we have created 3 new Gods. Each of these Gods has their own name and their own thoughts. Important: they have NOT 'inherited' the member variables from the God constructor. The member varibles are new, as each new instance of God is... 'new'. IE: God does not inherit anything from God, when God is at the top of the chain.

Prototypes
Once you understand that a Constructor is just a function used to create a 'new' instance and set new member variables within that instance... you will find it easy to comprehend what a Prototype is.

Prototypes are not 'created', that's the Constructor's job. Prototypes are linked. Lets say that God wanted to create Man. First God would need a constructor function by which to make the man. So lets code one...
 // Define Man's Constructor
Man = function Man( name ){
this.myName = name;
this.dna = 'ACGT';
}

Now you can create a new Man like this...
 Adam = new Man( 'Adam' );

Here we set the name-space 'Adam' to store a new instance of Man. When we invoke 'new Man', we want to pass Adam his name, so: 'new Man( 'adam' )'. Thus the Man construtor is run and Adam's member variables are set. But in this case... we have created a dead man (Adam can not think).

God can think but Adam can't. Wouldn't it be nice if Adam could inherit his thinking ability from his Creator? It would, and he can. This is where Prototype is used. Let's append the Man object...
 // Define Man's Constructor
Man = function Man( name ){
this.myName = name;
this.dna = 'ACGT';
}
// Define Man's Prototype
Man.prototype = new God;

Ahha! Now when ever a new Man is created, the new man gains the ability to think from his creator. Pointing Man's prototype to 'new God' creates a link that copies the member variables from the God constructor to the new instance of Man.

Prototypes are Links

Taking things to their logical conclusion: now that Man can think, he can realize that he is alone and needs a new Woman. Now we define the constructor function for Woman.
 Woman = function Woman( name ){
this.myName = name;
this.womb = true;
}
Woman.prototype = new Man;

Notice that Woman's prototype is Man. This means that any new Woman will inherit the Man constructor's member variables. Thus the Woman inherits DNA from the Man. Woman additionally gains a member variable called 'womb', which Man and God do not have.

So here is where the beauty really comes in: Woman can think, even though Man has no thinking ability in his constructor. This is because prototypes are links. And what do links form? Chains!

As you chained Woman to Man, every time you create a new instance of Woman, she inherits her member variables from new Man, who inherits his member variables from new God. Thus we have a chain of inheritance, and anything you set at the top level will filter down to the bottom unless you explicitly stop or redirect the flow of information.

All the Code
Lets put it all together and see what we get.
   // God constructor
God = function God(){
this.myName = 'YHWH';
this.thinks = true;
}

// Man constructor
Man = function Man( name ){
this.myName = name;
this.dna = 'ACGT';
}
// Man's Prototype is God's constructor
Man.prototype = new God;

//Woman constructor
Woman = function Woman( name ){
this.womb = true;
}

// Woman's Prototype is Mans's constructor & Man's prototype
Woman.prototype = new Man;

// Run the Man constructor against the new Woman object ( so Woman gets a name )
Woman.prototype.constructor = Man;

// A method to see inside the object
function inspect( being ){
var arr = {};
for( var i in being ){
arr[ i ] = being[ i ];
}
console.log( being.name || being.myName, arr );
}

/* Make an Adam & Eve from Woman & Man constructors...
...inheriting members from their prototypes links */
Adam = new Man( 'Adam' );
( Eve = new Woman ).constructor( 'Eve' );

// Console log for clarity
inspect( God );
inspect( Man );
inspect( Woman );
inspect( Adam );
inspect( Eve );

// constructor properties get added first
// then prototyped properties get inherited second

Results:

God Object prototype=Object
Man Object prototype=Object
Woman Object prototype=Object
Adam Object myName=Adam dna=ACGT thinks=true
Eve Object myName=Eve womb=true dna=ACGT thinks=true

Conclusion:
Pretty much everyone knows the account of Genesis, so we all know the fundamental differences between God, Man and Woman. Hopefully this has helped make Prototypes easier to understand for someone out there.

Prototypes are really very simple, but the terminology can be pretty confusing when you look at all the examples out there, especially if you are just beginning to learn Object Oriented patterns. I started learning OO in Java which was much easier to understand than JS. But now that I have been using Prototypal behavior in Javascript for a while, I have to say... I prefer it.

Tuesday, August 11, 2009

Switch vs. Array Index

At the last Javascript Meetup Cambridge I was showing off a Javascript Web Worker Network I have been working on for visualizing search queries. I showed the code to @geowa4, @AlbertoPL and another guy who's name I forget. @geowa4 pointed out that I could use look up the function directly from the object (which I had avoided thinking switch was faster), and someone else chimed in that the switch I was already using would be faster... and I was like... "yeah, get back in your place student n00b!"

Obviously... this had to be tested!

var obj = [];
var len = 10;
for( var i = 0; i < len; i++ ){
obj[i] = function(){ return 1 };
}
obj[ 10 ] = function( mn, inc ){
time = new Date().getTime() - time;
console.log( 'Method #' + mn + ': ' + time + 'ms, Check: ' + ( inc == 20000000 ) );
};

var time;
var times = 2000000;

function method1(){
time = new Date().getTime();
var inc = 0;
for( var t = 0; t < times; t++ ){
for( var i = 0; i < len; i++ ){
inc += obj[ i ]();
}
}
obj[ 10 ]( 1, inc ) ;

// run next method
method2();
}

function method2(){
time = new Date().getTime();
var inc = 0;
for( var t = 0; t < times; t++ ){
for( var i = 0; i < len; i++ ){
switch( i ){
case 0: inc += obj[0](); break;
case 1: inc += obj[1](); break;
case 2: inc += obj[2](); break;
case 3: inc += obj[3](); break;
case 4: inc += obj[4](); break;
case 5: inc += obj[5](); break;
case 6: inc += obj[6](); break;
case 7: inc += obj[7](); break;
case 8: inc += obj[8](); break;
case 9: inc += obj[9](); break;
}
}
}
obj[ 10 ]( 2, inc );
}

method1();


The results:
ARRAY --> Method #1: 257ms, Check: true
SWITCH --> Method #2: 7344ms, Check: true

Congratulations @geowa4 wins! IOU 1 beer.


Conclusion:
Never under-estimate the student n00b. Even if they don't know what they're talking about... they're probably still right. XD

Monday, August 10, 2009

Literal Object vs. Constructor Instances

At work today we were discussing memory management with Javascript objects in regards to speeding up the front-end of the search engine. The two methods being considered were using Prototypes vs. Literal objects to store a set of data. I knocked out a quick test to see what Firefox would make of these two methods and pretty much got the results we were expecting.

Method #1 - Constructor - 1,515,056k (1.5Gb of Ram)


function blank(){
this.DOM = document.createElement( 'div' );
this.DOM.innerHTML = "Lorem ipsum dolor sit amet... ...posuere cubilia Curae.";
}

var stacked = [];

var amount = 1000000;
for( var i = 0; i < amount; i++ ){
stacked[i] = new blank;
}


Method #2 - Literal - 1,800,000k+ CRASH! (1.8Gb of Ram)


blank = {
gen: function(){
var DOM = document.createElement( 'div' );
DOM.innerHTML = "Lorem ipsum dolor sit amet... ...posuere cubilia Curae.";
return DOM;
}
}
var stacked = [];
var amount = 1000000;
for( var i = 0; i < amount; i++ ){
stacked[i] = blank.gen();
}


NOTE:
The Literal Method did not finish running. It crashed, so the memory is not truly comparable. However, the speed at which the script ran was extremely slow. The Prototype Method pumped up the memory space like a flat tire, The Literal Method crawled so slowly it felt more like trying to pour hot lead into a straw basket.

CONCLUSION:
Careful what you use those literals for!

Saturday, August 8, 2009

Console log for Safari & Firefox


var Console={
log: function( message ){
try { window.opera.postError( message ); }
catch(e) { console.log( message ); }
}
}

Friday, July 31, 2009

Firebug AJAX Reading...

Want to read an async AJAX request in FireBug console?


AJAX=new XMLHttpRequest();
AJAX.open( 'POST', 'www.YourUrl.com', true );
AJAX.send( 'postKey=postVal' );
AJAX.onreadystatechange = function(){ console.log( AJAX ); }


This prints everything, not just a successful response. Very useful for learning about the XMLHttpRequest object and reading POST responses inside an authenticated session without any cross-domain trickery.