Data Structures in JavaScript
blog.benoitvallon.com
blog.benoitvallon.com
In JavaScript the hash based implementation is pretty trivial to write and some quick testing in node shows that it is dramatically faster.
Care to elaborate?
A string key for the underlying map is generated based on the data type of the element being added in the set. If you're adding an object into the set, the object is mutated so that it stores a unique ID. The object's unique ID is used to form the string key that will identify this object in the set.
Note how goog.structs.Set.getKey_ is used in the add() method: https://github.com/google/closure-library/blob/v20160125/clo...
This is how the library obtains the unique ID of an object: https://github.com/google/closure-library/blob/v20160125/clo...
Also, if this was being done for ES5+ code, then either setting that property to non-enumerable or using something like Symbols would be cool since it would hopefully have a reduced impact on other code.
Both libraries provide their own implementation of a Set though, so in practice you would just use the library provided one.
The code they use has the same limitation. It adds / removes / ensures the uniqueness of elements in the set by using Array.indexOf(...), which only works for strings and things that can be uniquely coerced into strings.
So, given this limitation, using an Object-based set would be vastly more performant.
var set = []
var foo = {foot: 1}
var bar = {bart: 2}
set.push(foo)
set.indexOf(foo) //0
set.indexOf(bar) //-1
"indexOf() compares searchElement to elements of the Array using strict equality (the same method used by the ===, or triple-equals, operator)."[0]MDN has the link to the ES5 specification, but the key part is 9(c)(ii):
"Let same be the result of applying the Strict Equality Comparison Algorithm to searchElement and elementK."
[0] - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
var elem = {foo:"bar"}
var set = [elem]
set.indexOf(elem) // 0
set.indexOf({foo:"bar"}) // -1
So I guess the strict equality comparison is using some kind of internal objectId rather than the property name and values of the objects? I guess depend on how you want to define "uniqueness" for your set...So
var x = {foo:"bar"}
var y = {foo:"bar"}
var z = x
x === y //false
x === z //true
This is specified in the ES3 document[0] at 11.9.6(13):"13. Return true if x and y refer to the same object or if they refer to objects joined to each other (see 13.1.2). Otherwise, return false."
[0] - http://www.ecma-international.org/publications/files/ECMA-ST...
The load factor (entries/bucket before you resize) varies greatly depending on the hashmap's addressing and collision resolution. Robin-hood hashing allows ridiculously high open-addressing load factors for instance (above 0.9 on an open-addressing linear-probed map, an open-addressing hash table can't go beyond 1), meanwhile separate-chaining allows load factors way above 1 (buckets are sequences and conflicting entries are appended to the sequence)
These data-structure implementations make me feel that, even though it is crazy, it might just work. This seems to have come out very clean and easy to implement.
[0] - http://duktape.org/
[1] https://github.com/runtimejs/runtime [2] https://www.destroyallsoftware.com/talks/the-birth-and-death...
- Memory management can be simulated by have a fixed length array, representing your total RAM, and somehow marking index ranges as "reserved". - You can simulate some hardware devices by exposing browser capabilities. Each, you could print a character, by writing to a virtual port or register (actually implemented as an array), then later in your VM update loop, reading the values in the array, interpreting the instructions, and updating the DOM as approprite.
And all from the comfort of your browser!
You could check out some emulators that have been ported to JavaScript; these are simulating hardware like the NES, and have the capability to run operating systems.
JavaScript is great because you can learn it in the afternoon and master it in a few years and has a nice subset of lisp-like features.
It would be a toy to prototype in. Easy to use, and easy to modify. Nothing serious.
I looked around in there and have no idea how any of that works or how any of the modules relate.