There's another, more direct solution to the "running include? on an Array takes longer and longer as the array gets bigger" problem: use a Set.
Add require 'set' to the top of your file; the library ships with Ruby but isn't loaded by default.
Then replace @@taken_names = [] with @@token_names = Set.new.
Under the hood, Set uses a Hash to get constant-time lookups - source. See your favorite Ruby internals book for details on this - I'm a fan of Ruby Under A Microscope.
BTW, I was curious about the pitfalls of representing names as integers and then converting them - so I put together some code. Note: I've been writing a lot of Elixir lately, and the style reflects some of that.
There's another, more direct solution to the "running
include?
on anArray
takes longer and longer as the array gets bigger" problem: use aSet
.Add
require 'set'
to the top of your file; the library ships with Ruby but isn't loaded by default.Then replace
@@taken_names = []
with@@token_names = Set.new
.Under the hood,
Set
uses aHash
to get constant-time lookups - source. See your favorite Ruby internals book for details on this - I'm a fan of Ruby Under A Microscope.BTW, I was curious about the pitfalls of representing names as integers and then converting them - so I put together some code. Note: I've been writing a lot of Elixir lately, and the style reflects some of that.
This would make using the
Set
approach even more efficient, sinceInteger
objects are 8 bytes instead of 40 bytes forString
s.