Closed staltz closed 2 years ago
Given that this is a follow up PR, I think it's rather safe to not issue a breaking change, and just bump minor instead.
There could be a performance problem here if converting from string to buffer isn't cheap. Because for each different record, we would do the conversion 'value'
=> Buffer.from('value')
.
I could add another cache for these conversions though. What do you think?
Might be best to benchmark :)
Well, here are some results.
targetBuf
cacheconst cache1 = new WeakMap()
function seekKeyCached(buffer, start, target) {
let cache2 = cache1.get(buffer)
if (!cache2) cache1.set(buffer, (cache2 = new Map()))
let cache3 = cache2.get(start)
if (!cache3) cache2.set(start, (cache3 = new Map()))
if (typeof target !== 'string') throw new Error('x')
if (cache3.has(target)) {
return cache3.get(target)
} else {
const result = seekKey(buffer, start, target)
cache3.set(target, result)
return result
}
}
BIPF.seek(buffer) 1111.111111111111
BIPF.seekCached(buffer) 1666.6666666666667
...
BIPF.seek(uniqueMsg) 1111.111111111111
BIPF.seekCached(uniqueMsg) 1666.6666666666667
targetBuf
cacheconst cache1 = new WeakMap()
const targetCache = new Map()
function seekKeyCached(buffer, start, target) {
let cache2 = cache1.get(buffer)
if (!cache2) cache1.set(buffer, (cache2 = new Map()))
let cache3 = cache2.get(start)
if (!cache3) cache2.set(start, (cache3 = new Map()))
if (typeof target !== 'string') throw new Error('x')
let targetBuf = targetCache.get(target)
if (!targetBuf) {
targetBuf = Buffer.from(target)
targetCache.set(target, targetBuf)
}
if (cache3.has(target)) {
return cache3.get(target)
} else {
const result = seekKey(buffer, start, targetBuf)
cache3.set(target, result)
return result
}
}
BIPF.seek(buffer) 1000
BIPF.seekCached(buffer) 1666.6666666666667
...
BIPF.seek(uniqueMsg) 1000
BIPF.seekCached(uniqueMsg) 1428.5714285714287
Yeah, seems like targetBuf
cache doesn't help. This PR is ready for review @arj03
Context: https://github.com/ssb-ngi-pointer/jitdb/pull/209#issuecomment-1087482324
I opted to remove support for buffer
target
and keep only stringtarget
because:WeakMap
(because strings don't get deallocated)Map
(because it would retain these buffers from being GCd)target
is anyway converted only once whenseekKeyCached
callsseekKey
For the record, perf bench: