Skip to content Skip to sidebar Skip to footer

Javascript: Fast Random Indexing Of Object Keys

I am attempting to randomly select a random property from an object that I use as a dictionary for fast indexing. Consider the following code: As you can see, using Object.keys()

Solution 1:

If caching the Object.keys array is infeasible, you can maintain your own copy with a Proxy:

functiongenerateKeyTracker (keysPropertyName) {
  const set = newSet();
  functiondefineProperty (target, property, descriptor) {
    target[property] = descriptor.value;

    if (set.has(property)) returntrue;

    set.add(property);
    target[keysPropertyName].push(property);
    returntrue;
  }
  functiondeleteProperty (target, property) {
    delete target[property];
    
    if (!set.delete(property)) returntrue;

    target[keysPropertyName] = target[keysPropertyName].filter(key => key !== property);
    returntrue;
  }
  return {defineProperty, deleteProperty};
}

//Create test dictionaryvar dict = newProxy(
  Object.defineProperty({}, '__keys', {
    configurable: true,
    enumerable: false,
    writable: true,
    value: []
  }),
  generateKeyTracker('__keys')
);

for(var i = 0; i < 1e4; i++) {
  var num = Math.random() * 1e6 << 0;
  dict[num] = { Id: num };
}

//FuzzconstNUM_RUNS = 1e6;
var start = performance.now();
for(var i = 0; i < NUM_RUNS; i++)
  getRandom(dict);
var end = performance.now();

var runTime = end - start;
var timePerCall = (runTime / NUM_RUNS);
console.log(`Total Calls: ${NUM_RUNS}`);
console.log(`Total Runtime: ${runTime} ms`);
console.log(`Time Per Call: ${timePerCall * 1e6} ns`);

functiongetRandom(dict) {
  var index = Math.random() * dict.__keys.length << 0;
  return dict[dict.__keys[index]];
}

This uses traps on property creation and deletion to keep track of dict's property keys, which are stored in the non-enumerable property dict.__keys.

Post a Comment for "Javascript: Fast Random Indexing Of Object Keys"