平均 GET 操作应该在 1 毫秒以下,从 189ns 到 1024 个条目(内存中 349KB)到 888ns 到 27,648 个条目(6MB 在内存中)。具有 27k 个条目的条目的最大延迟为 44,000ns。但是,如果平均时间对您来说很重要,而不是经常出现高延迟,那么这可能基本上就是您想要的。我认为它可以进一步优化,但不确定会获得什么收益。
typedef unsigned int uintptr;
typedef unsigned int uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
namespace anything { namespace linklist {
typedef struct _HDR {
void *next;
void *prev;
} HDR;
void *next(void *ptr) {
if (ptr == 0) {
return 0;
}
return ((void**)ptr)[0];
}
void add(void **chain, void *toadd) {
((void**)toadd)[0] = *chain;
((void**)toadd)[1] = 0; /* set previous */
/* set previous link if valid pointer */
if (*chain)
((void**)*chain)[1] = toadd;
*chain = toadd;
}
}}
namespace anything{ namespace hash {
typedef struct _B {
MASS_LL_HDR llhdr;
uint32 id;
union {
struct _B *chain;
uintptr value;
};
} B;
typedef struct _HT {
B *buckets;
uint16 depth;
uint8 bbl;
} HT;
void init(HT *ht, uint8 bbl) {
ht->buckets = 0;
ht->bbl = bbl;
}
void _free(B **chain, uint16 dcnt, uint16 dcntmax, uint32 *_m) {
B *ba, *_ba;
for (ba = *chain, _ba = 0; ba; ba = _ba) {
_ba = (B*)mass_ll_next(ba);
if (dcnt < dcntmax - 1) {
_free(&ba->chain, dcnt + 1, dcntmax, _m);
*_m = *_m + 1;
dfree(ba);
}
}
/* zero the chain out */
*chain = 0;
}
void free(HT *ht) {
uint32 m;
uint16 dm;
dm = (sizeof(uintptr) * 8) / ht->bbl;
m = 0;
_free(&ht->buckets, 0, dm, &m);
}
int get(HT *ht, uintptr k, uintptr *v) {
uintptr a;
B *ba, **cur;
uint16 bi, lcnt;
uint32 mask;
lcnt = (sizeof(uintptr) * 8) / ht->bbl;
cur = &ht->buckets;
mask = ~(~0 << ht->bbl);
for (bi = 0; bi < lcnt; ++bi) {
a = (k >> (bi * ht->bbl)) & mask;
for (ba = *cur; ba; ba = (B*)mass_ll_next(ba)) {
if (ba->id == a) {
break;
}
}
if (!ba) {
return 0;
}
cur = &ba->chain;
}
*v = ba->value;
return 1;
}
void put(HT *ht, uintptr k, uintptr v) {
uintptr a;
B *ba, **cur;
uint16 bi, lcnt;
uint32 mask;
lcnt = (sizeof(uintptr) * 8) / ht->bbl;
cur = &ht->buckets;
mask = ~(~0 << ht->bbl);
for (bi = 0; bi < lcnt; ++bi) {
a = (k >> (bi * ht->bbl)) & mask;
for (ba = *cur; ba; ba = (B*)mass_ll_next(ba)) {
if (ba->id == a) {
break;
}
}
if (!ba) {
ba = (B*)dmalloc(sizeof(B));
ba->id = a;
ba->chain = 0;
mass_ll_add((void**)cur, ba);
}
cur = &ba->chain;
}
ba->value = v;
}
}}
anything::hash::HT ht;
anything::hash::init(&ht, 1);
anything::hash::put(&ht, key, value);
if (!anything::hash::get(&ht, key, &value) {
printf("not found!\n");
}
您可以使用anything::hash::init(&ht, 4) 将内存使用量减少到每15000 个条目大约900kb,但这会增加延迟。