Skip to content

Commit 8715eeb

Browse files
committed
Iterative .hasPrefix (replacing recursive)
20× faster, like `has`.
1 parent 48874c3 commit 8715eeb

2 files changed

Lines changed: 21 additions & 10 deletions

File tree

benchmark/hasPrefix.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const benchmark = require('benchmark')
2+
const AKM = require('../main.js')
3+
4+
const letters = 'abcdefghijklmnopqrstuvwxyz'.split('')
5+
6+
const lettersMap = new AKM()
7+
for (const x of letters) lettersMap.set(Array(100).fill(x), true)
8+
9+
new benchmark.Suite()
10+
.add('100-item hasPrefix', () => {
11+
for (const x of letters) lettersMap.hasPrefix(Array(100).fill(x))
12+
})
13+
.on('cycle', ev => console.log(String(ev.target)))
14+
.run()

main.js

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class ArrayKeyedMap {
7878
this._size = 0
7979
}
8080

81-
hasPrefix (path) { return hasPrefix(path, this._root, this) }
81+
hasPrefix (path) { return hasPrefix.call(this, path) }
8282

8383
get [Symbol.toStringTag] () { return 'ArrayKeyedMap' }
8484

@@ -175,16 +175,13 @@ function del (path) {
175175
return hadPreviousValue
176176
}
177177

178-
const hasPrefix = (path, store) => {
179-
switch (path.length) {
180-
case 0:
181-
return true
182-
default: {
183-
const [next, ...rest] = path
184-
const nextStore = store.get(next)
185-
return nextStore ? hasPrefix(rest, nextStore) : false
186-
}
178+
function hasPrefix (path) {
179+
let map = this._root
180+
for (const item of path) {
181+
map = map.get(item)
182+
if (!map) return false
187183
}
184+
return true
188185
}
189186

190187
const entries = function * (path, store) {

0 commit comments

Comments
 (0)