Exploring Javascript Hash Maps

Nicholas Echevarria
3 min readOct 11, 2020

--

Photo by Markus Spiske on Unsplash

About a week ago, I stumbled on an article by Johannes Baum titled Stop Using Objects as Hash Maps in Javascript. Being that my card game project Triple Triad prominently uses an object-based hash map as a core part of how it works, the article inspired my goal of refactoring relevant parts of the project’s code.

Admirable, right? After reading the article, I figured I could not only increase the project’s speed and efficiency but also really experience the challenge of refactoring essential code. After much research and toying around with different Maps in a Repl I established, the answer is much more complicated than it originally seemed. (What a surprise, huh?)

“Alexa, play Maps by the Yeah Yeah Yeahs”

Photo by Andrew Neel on Unsplash

In his article, Baum does an incredible job of going over Javascript maps, defining them as “one of the most frequently used data structures in daily programming,” adding that “It keeps key-value pairs that can easily be accessed by their keys.” Sounds like an object, sure, and most of the time an object is used for this very purpose. (e.g. my comparisonMap hash map in Triple Triad)

However, Baum continues on to list the properties of a Map and in doing so, why they’re superior to objects. In sum:

  • Javascript Maps can have keys of any type versus only symbols and strings for objects.
  • Determining the size of a Map is possible in O(1) time, while it takes O(n) steps for a plain object.
  • entries of a Map can be retrieved in constant time, while the number of entries of a plain object must be counted, which takes O(n) time.
  • Maps are directly iterable while objects need their keys to be obtained first.
  • Maps maintain key order based on order of insertion. There is not set order with objects.
  • Objects are initialized with keys due to its prototype, while Maps do not have any keys.

Baum then ends on a definitive note, calling for objects used this way to be replaced with maps. And to that, I said “Hold my beer”.

Mission: Refactoring Triple Triad

My main goal was to refactor comparisonMap:

As you can see, it’s quite the handful. Still, it’s essential, which is why its the prime candidate for refactoring:

Side-by-side, nothing particular stands out. While it may look the same, Map is supposed to be faster to iterate over, so I decided to test it out.

Using console.time() to test function speed

To function, Triple Triad needs to access the deepest values for each board position, their keys being position, playedCard_value, and otherCard_value. So, to determine which version of comparisonMap was faster, I decided to use console.time() to see just how fast it was to log each value to the console. By surrounding a function with console.time() and console.timeEnd(), we can determine how long it takes to execute:

(Please note that I am no expert so my way of testing speed and the value of testing a single, very simple function probably isn’t the best data to begin with.)

The above is really simple function but it gets the job done by logging the information Triple Triad needs. It uses the Map method .get() to retrieve the correct position. The result? An execution time of 7.390ms.

The below uses the standard way to access an object and iterates through the result:

The result here? 5.840ms. That a difference of 2ms which may not be much but compounded can add up. And what’s more, this result contradicts Baum’s assertion that Maps are always a better, faster alternative instead of objects. In the end, maybe my comparisonMap as it is is more than fine. More testing will need to be done to verify that, however!

Baum isn’t incorrect, per se, and I’m no expert at Javascript. But, after much digging around and practicing, I’ve come to understand Maps in Javascript some more while also understanding that every tool has its place and time to be used — even with Javascript.

--

--

No responses yet