我期待实现的O(1)查找为binary quadkeysHashtable的64位整数
我知道有是Javascript没有真正的哈希表,而不是使用对象和O(1)查找与它们的属性,但问题在于键总是转换为字符串。
我怀疑有超过1000万的条目在内存中,如果我不得不依赖键是字符串,并且平均quadkey字符串是11.5个字符,相当于(1000万条记录* 11.5长度* 2个字节) = 230,000,000字节或230 MB。
相比存储为Int64的(10万个条目* 8个字节)= 80000000个字节或80 MB
我知道的Int64不使用JavaScript原生支持,但也有可能与协助的术语库做我想要的按位操作。
现在,尽管存在可以处理int64的库,它们最终是不是真正代表8个字节的对象,所以我相信我不能在散列表中使用任何int64库,而是考虑使用2-depth哈希表与两个int32。第一个键是前4个字节,第二个键是最后4个字节。它不如1次操作查找找到一个值,但2次操作仍然足够好。但是,如果所有的键都存储为字符串,或者所有数字都是双精度浮点格式数字(8字节),那么每个散列条目将占用16个字符的事实,我觉得这是不值得的字节(两个“int32”数字)。
我的问题是:
1.如果您存储号码为重点,以一个属性,它会占用8个 字节的内存或将其转换为字符串,并采取了 长度* 2字节?
- 是否有二进制quadkeys编码到双精度 浮点格式数目的标准的方式,JavaScript的已通过, 即使号码是没有意义的,则基础位提供了一个 目的(唯一标识一个构造)。
PS:我纪念这一具有的NodeJS因为有可能存在,可以帮助我的最终目标库
编辑1:
似乎是可能的Map()
和节点0.12.x +
至于我能够使用int64 lib(bytebuffer)并将64int转换为缓冲区。
我想仅仅使用缓冲区作为Map()的键,但它不会让我作为缓冲区内部的对象,每个实例都充当Map()的新键。
所以我认为把缓冲区变回原生类型,一个64位双。
使用readDoubleBE
我读取缓冲区为double,它代表我的64int二进制文件,并成功让我在地图中使用它并允许O(1)查找。
var ByteBuffer = require("bytebuffer");
var lookup = new Map();
var startStr = "123123738232777";
for(var i = 1; i <= 100000; i++) {
var longStr = startStr + i.toString();
var longVal = new ByteBuffer.Long.fromValue(longStr);
var buffer = new ByteBuffer().writeUint64(longVal).flip().toBuffer();
var doubleRepresentation = buffer.readDoubleBE();
lookup.set(doubleRepresentation, longStr);
}
console.log(exists("12312373823277744234")); // true
console.log(exists("123123738232777442341232332322")); // false
function exists(longStr) {
var longVal = new ByteBuffer.Long.fromValue(longStr);
var doubleRepresentation = new ByteBuffer().writeUint64(longVal).flip().toBuffer().readDoubleBE();
return lookup.has(doubleRepresentation);
}
该代码是草率的,可能有快捷键我缺少,所以任何建议/提示,欢迎。
理想情况下,我想利用bytebuffer的varints,这样我可以节省更多的内存,但我不确定这是否可能在Map中,因为我无法使用缓冲区作为关键字。
编辑2:
使用memwatch-next我能看到,最大堆大小为497962856个字节,这种方法与设置(),而使用集的字符串()为1111082864个字节。那大约是500MB和1GB,这与80MB和230MB相差甚远,不知道额外内存使用的来源。对于这些内存测试,我使用Set
而不是Map
这种方式,它应该只存储数据结构中唯一的密钥。 (使用Set作为存在检查器,其中Map将用作查找)
如果您使用nodejs 4+,那么您可能需要查看_Map_ [MDN:Map - 对比和映射图](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ Global_Objects/Map#Objects_and_maps_compared):'[...]一个对象的键是字符串和符号,它们可以是Map的任何值[或者也可以是_WeakMap_。 –
我希望能创建一个兼容0.12.x的节点包,因为我自己的应用程序现在是0.12,但很高兴知道这样的事情存在4+。更糟糕的病例只是更新我的应用程序,以支持4 – ParoX
如果它是一个选项,你可以使用' - 0.12.x'和'--harmony',但老实说,我不知道'Map'是否和谐稳定(但我会这样猜测)。 –