我期待實現的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'是否和諧穩定(但我會這樣猜測)。 –