You are reading a single comment by @Gordon and its replies. Click here to read the full conversation.
  • Have you checked out http://www.espruino.com/Performance and http://www.espruino.com/Internals ?

    If you something like A.foo() it does a linear search in A, but then if A is some kind of built-in class (or has a prototype that is one) it'll do a binary search through the built-in functions.

    Variable names of 4 chars or left are stored in a single JsVar, so are very efficient (so minified code works great). Also, if the value they represent is small (for instance a 16 bit int) it is stored in the exact same JsVar. If not (for instance it's an object) it points to another JsVar that represents the object.

    The initial search is pretty quick too, as Espruino does something like:

    while (var) {
      if (var.first4Bytes==first4BytesOfName) 
        var.checkProperly(name);
      var = var.next;
    }
    

    To take advantage of this, modules are already minified.

    Another question has to do with namespacing of vars.

    Because you've got linked lists, if you've got a bunch of functions/variables you're better off adding your own tree structure by putting them in objects as you suggest. Generally you'd do that anyway though...

    So for instance my car's ECU uses Espruino, and it has a bunch of pins that control things. I put those in an object called PINS, so now Espruino isn't searching through them for everything, but only when I access PINS.tempSensor or whatever it is.

    Finally, if I have obj1 = { foo: "bar" }; obj2 = obj1, then these two variables both point to the same object.

    It's best to poke around with the trace() command:

    >obj1 = { foo: "bar" }; obj2 = obj1
    ={ 
      "foo": "bar"
     }
    >trace()
    #1[r2,l1] Object { 
      // internal stuff here you don't care about
      #18[r1,l2] Name String [1 blocks] "obj1"    #17[r2,l1] Object { 
          #22[r1,l2] Name String [1 blocks] "foo"        #23[r1,l1] String [1 blocks] "bar"  
        } 
      #24[r1,l2] Name String [1 blocks] "obj2"    #17[r2,l1] Object { 
          #22[r1,l2] Name String [1 blocks] "foo"        #23[r1,l1] String [1 blocks] "bar"  
        } 
    }
    

    So you actually have just 5 JsVars (the number with the # in front is a unique ID):

    • 2 for obj1 and obj2
    • 1 for the object
    • 1 for foo
    • 1 for bar

    But if foo was an int...

    >obj1 = { foo: 42 }; obj2 = obj1   
    ={ "foo": 42 }
    >trace()                        
    #1[r2,l1] Object { 
      // stuff
      #18[r1,l2] Name String [1 blocks] "obj1"    #5[r2,l1] Object { 
          #36[r1,l2] Name String [1 blocks] "foo"= int 42
        } 
      #24[r1,l2] Name String [1 blocks] "obj2"    #5[r2,l1] Object { 
          #36[r1,l2] Name String [1 blocks] "foo"= int 42
        } 
    }
    

    Suddenly its only 4 JsVars, because both foo and 42 get jammed into the same block.

    In the same way, if you had a long name that wouldn't fit in one var, another one gets added:

    >obj1 = { fooBarBaz: "bar" }; obj2 = obj1  
    ={ 
      "fooBarBaz": "bar"
     }
    >trace(obj1)
    #41[r2,l1] Object { 
      #23[r1,l2] Name String [2 blocks] "fooBarBaz"    #46[r1,l1] String [1 blocks] "bar"  
    }
    

    Now the object itself takes 4 blocks, so the whole thing (obj1 and obj2) takes 6.

About

Avatar for Gordon @Gordon started