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:
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
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:
To take advantage of this, modules are already minified.
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 accessPINS.tempSensor
or whatever it is.It's best to poke around with the
trace()
command:So you actually have just 5 JsVars (the number with the
#
in front is a unique ID):foo
bar
But if
foo
was an int...Suddenly its only 4 JsVars, because both
foo
and42
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:
Now the object itself takes 4 blocks, so the whole thing (obj1 and obj2) takes 6.