Performance: inline- vs. prototype-defined methods ?

G

Gerald S

hi,

got a performance problem; situation is as described below (see "Version
Inline"), i've got a javascript class item with many methods defined
inside and with every call to "new item()" the js interpreter has to
look through all the method definitions (did a profile using Venkman)
which takes too much time for me ..

would it make a difference if i define these methods outside the
constructor via .prototype (see "Version Prototype") ??

Version Inline:

item = function () {
this.myMethod1 = function() { .. }
this.myMethod2 = function() { .. }
this.myMethod3 = function() { .. }
...
this.myMethod999 = function() { .. }
}


Version Prototype:

item = function () {

}

item.prototype.myMethod1 = function() { .. }
item.prototype.myMethod2 = function() { .. }
item.prototype.myMethod3 = function() { .. }
...
item.prototype.myMethod999 = function() { .. }



many thanks in advance !!

-
Gerald Stampfel
(e-mail address removed)
 
G

Gerald S

Duncan said:
Yes it will make a difference since you will only be setting up the methods
once instead of every time you create an object, also if you have a lot of
objects you will be using less memory so there may be a gain there. Calls
to the methods may be slightly slower but that is unlikely to be
noticeable.

ok, thanks!!

but if i do it the .prototype-way, there is another problem. consider
the following situation:


item = function () {
var privateVar;

function doInternalStuff();
}

item.prototype.myMethod1 = function() { .. }
item.prototype.myMethod2 = function() { .. }
item.prototype.myMethod3 = function() { .. }
...
item.prototype.myMethod999 = function() { .. }


two issues:
1) i can't access privateVar from my myMethodXXX methods (or can i?)
2) i can't call doInternalStuff() from my myMethodXXX methods

i could expose both to the public, but is there a way to keep them
private AND use them. any patterns ?

thanks again ..

-
Gerald Stampfel
(e-mail address removed)
 
J

Julian Turner

Gerald said:
ok, thanks!!

but if i do it the .prototype-way, there is another problem. consider
the following situation:


item = function () {
var privateVar;

function doInternalStuff();
}

item.prototype.myMethod1 = function() { .. }
item.prototype.myMethod2 = function() { .. }
item.prototype.myMethod3 = function() { .. }
...
item.prototype.myMethod999 = function() { .. }


two issues:
1) i can't access privateVar from my myMethodXXX methods (or can i?)
2) i can't call doInternalStuff() from my myMethodXXX methods

i could expose both to the public, but is there a way to keep them
private AND use them. any patterns ?

There are.

Search this group for posts from Richard Cornford: there have been
plenty of discussions on this subject.

Take a look at:-

<URL:http://www.litotes.demon.co.uk/js_info/private_static.html>
<URL:http://jibbering.com/faq/faq_notes/closures.html>
<URL:http://www.crockford.com/>

Regards

Julian
 
J

Julian Turner

Julian Turner wrote:

[snip]
i could expose both to the public, but is there a way to keep them
[snip]

Here is a quick example:-

var myObject=(function(){

var myPrivateVar=1;
var myPrivateFunction=function(){
alert("Hello from Private "+myPrivateVar);
}

function Constructor(){}

Constructor.prototype.alert=function()
{
myPrivateFunction();
myPrivateVar++;
}

return Constructor;
})();


var o1=new myObject();
var o2=new myObject();
o1.alert();
o2.alert();


Regards

Julian
 
J

Julian Turner

Duncan Booth wrote:

[snip]
Except that in Gerald's original post 'privateVar' was a private instance
variable and you've demonstrated how to make a private variable shared
between all instances which is not the same thing at all.
[snip]

Fair point.
 
J

Julian Turner

Julian said:
Duncan Booth wrote:

[snip]
Except that in Gerald's original post 'privateVar' was a private instance
variable and you've demonstrated how to make a private variable shared
between all instances which is not the same thing at all.
[snip]

Fair point.

[This is a duplicate message, as one posted earlier did not appear].

Putting my head above the parapet again, here is a very rough hack to
create the illusion of private instance variables. I am sure others
will have better ideas of course. It uses a count variable to uniquely
identify each instance, and a private object to store the private
variable.


var myObject=(function(){

var count=0;
var private={};

function Constructor(nPrivate){
this.id=count++;
private[this.id]=nPrivate;
}

Constructor.prototype.alert=function(){
alert(private[this.id]);
}

return Constructor;
})();


var o1=new myObject("private 1");
var o2=new myObject("private 2");
o1.alert();
o2.alert();

Regards

Julian
 
J

Julian Turner

Julian said:
Duncan Booth wrote:

[snip]
Except that in Gerald's original post 'privateVar' was a private instance
variable and you've demonstrated how to make a private variable shared
between all instances which is not the same thing at all.
[snip]

Putting my head above the parapet again, here is some kind of hack (by
no means perfect) which includes a counter to count each instance
created and uses a global private object to store private instance
variables:-

var myObject=(function(){

var count=0;
var private={};

function Constructor(nPrivate)
{
this.id=count++;
private[this.id]=nPrivate;
}

Constructor.prototype.alert=function()
{
alert(private[this.id]);
}

return Constructor;
})();


var o1=new myObject("Private Value 1");
var o2=new myObject("Private Value 2");
o1.alert();
o2.alert();

Regards

Julian
 
J

Julian Turner

Duncan Booth wrote:

[snip]
a) I guess if you tested it you used IE. It will give you a syntax error on
Firefox or anything close to a conforming ecmascript implementation.

Right. I will give it a try in Firefox. Did you have a record of the
syntax error it gave?

[snip]
b) It leaks memory. The private values are never released.

Good point. It could require some form of garbage collection for the
private object.

If at first you don't succeed...

Regards

Julian
 
J

Julian Turner

Duncan said:
The actual message is kind of irrelevant (and not at all informative).
'private' is a reserved word so you can't use it as a variable name, all
you have to do is rename it.

Doh. Of course.

Here are couple of other attempts to play with:-

1. Priviledged Accessor (so named by Douglas Crockford)

var myObject=(function(){

function Constructor(v)
{
var privateInstance=v;

this.getPrivateInstance=function(){
return privateInstance;
}
}

Constructor.prototype.alert=function()
{
alert("Private Instance "+this.getPrivateInstance());
}

return Constructor;
})();


2. Private Instance is copied to common private variable for use. I
am sure this has lots of other potential problems, apart from lacking
elegance.

var myObject=(function(){

var privateHolder;

function getPrivate()
{
return privateHolder;
}

function Constructor(v)
{
var vPrivate=v;

this.openPrivate=function(){
privateHolder=v;
}

this.closePrivate=function(){
privateHolder=null;
}
}

Constructor.prototype.alert=function()
{
this.openPrivate();

alert(getPrivate());

this.closePrivate();
}

return Constructor;
})();


Regards

Julian
 
G

Gerald S

thanks Julian and Duncan for you solutions, didn't know you could do
such crazy things with this language!! :)

in my case the problem is i want to distinguish between private <->
public AND define the methods for an object outside of the consructor (
because [as stated in the first post of this thread] i have to create
many instances of this class.

but i guess after reading your solutions and trying a few things this is
not so easy (if not impossible). i'm not into javascript for very long,
my mind is still thinking in java-terms ..

the solution for me is to give up on seperating private and public, just
use some naming conventions for pseudo-private things and make
everything public like this:

item = function () {
this._privateFieldA = 0;
this._privateFieldB = 0;
this._privateFieldC = 0;
..
}

item.prototype.manipulateA = function() {
this._privateFieldA++;
}

var myObj = new item();

and using the object like myObj.manipulateA() [even if it could be done
using myObj._privateFieldA++]


thanks for you effort guys!

-
Gerald Stampfel
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top