mapbox / geobuf

A compact binary encoding for geographic data.
ISC License
967 stars 84 forks source link

alternative fix for #90 (ensure property key strings are serialized in correct order) #92

Closed ivorblockley closed 6 years ago

ivorblockley commented 6 years ago

Alternative to pull request #91

ivorblockley commented 6 years ago

IMHO this approach is cleaner than #91. The only remaining consideration is performance. The performance question is effectively the speed difference between associative_array[key] === undefined and !map.has(key) (assuming property-heavy geojson inputs with repeated property names) along with the speed of associative_array[key] vs map.get(key).

ivorblockley commented 6 years ago

Using this benchmark (based on https://jsperf.com/es6-map-vs-object-properties/88 ):

'use strict';

var Benchmark = require('benchmark');
var suite = new Benchmark.Suite();
var i;

var maxnum = 100000;

function randomString()
{
    var text = '';
    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

    for (var i = 0; i < 5; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

var preComputedRandomKeys = [];
var preComputedRandomVals = [];

for (i = 0; i < maxnum; i++) {
    preComputedRandomKeys[i] = randomString();
    preComputedRandomVals[i] = randomString();
}

var map = new Map();
var obj = {};

for (i = 0; i < maxnum; i++) {
    map.set(preComputedRandomKeys[i], i);
    obj[preComputedRandomKeys[i]] = i;
}

suite.add('Mapget', function () {
    for (i = 0; i < maxnum; i++) {
        var v = map.get(preComputedRandomKeys[i]);
    }
});

suite.add('Objget', function () {
    for (var i = 0; i < maxnum; i++) {
        var v = obj[preComputedRandomKeys[i]];
    }
})

// add listeners
    .on('cycle', function (event) {
        console. log(String(event.target));
    })
    .on('complete', function () {
        console.log('Fastest is ' + this.filter('fastest').map('name'));
    })
// run async
    .run({'async': true});

I get:

$ node mapget_vs_objget.js 
Mapget x 95.43 ops/sec ±0.65% (67 runs sampled)
Objget x 106 ops/sec ±0.41% (66 runs sampled)
Fastest is Objget

Results for checking if a key exists are similar (presumably both check and get operations involve a key lookup).

mourner commented 6 years ago

Closing in favor of #93