Performance: inline- vs. prototype-defined methods ?

Discussion in 'Javascript' started by Gerald S, Jan 31, 2006.

  1. Gerald S

    Gerald S Guest

    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
     
    Gerald S, Jan 31, 2006
    #1
    1. Advertising

  2. Gerald S

    Gerald S Guest

    Duncan Booth wrote:
    > 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
     
    Gerald S, Jan 31, 2006
    #2
    1. Advertising

  3. Gerald S wrote:

    > Duncan Booth wrote:
    > > 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 ?


    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
     
    Julian Turner, Jan 31, 2006
    #3
  4. Julian Turner wrote:

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

    [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
     
    Julian Turner, Jan 31, 2006
    #4
  5. 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.
     
    Julian Turner, Feb 1, 2006
    #5
  6. Julian Turner wrote:

    > 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
     
    Julian Turner, Feb 1, 2006
    #6
  7. Julian Turner wrote:

    > 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
     
    Julian Turner, Feb 1, 2006
    #7
  8. 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
     
    Julian Turner, Feb 1, 2006
    #8
  9. Duncan Booth wrote:

    > 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
     
    Julian Turner, Feb 1, 2006
    #9
  10. Gerald S

    Gerald S Guest

    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
     
    Gerald S, Feb 3, 2006
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nish
    Replies:
    4
    Views:
    544
    Thomas Stegen
    Oct 8, 2004
  2. Oodini
    Replies:
    1
    Views:
    1,845
    Keith Thompson
    Sep 27, 2005
  3. June Lee
    Replies:
    2
    Views:
    846
    Jim Cobban
    Apr 13, 2008
  4. Replies:
    9
    Views:
    231
    Thomas 'PointedEars' Lahn
    May 26, 2006
  5. Replies:
    3
    Views:
    289
Loading...

Share This Page