Skip to content

Instantly share code, notes, and snippets.

@JaosnHsieh
Last active February 15, 2022 08:45
Show Gist options
  • Save JaosnHsieh/94be2c0d7e099af3cc4b48510a17bde4 to your computer and use it in GitHub Desktop.
Save JaosnHsieh/94be2c0d7e099af3cc4b48510a17bde4 to your computer and use it in GitHub Desktop.
speedometer test, a window sliding algorithm to calculate streaming data speed in javascript, cloud be used in any node.js stream
var tick = 1;
var maxTick = 65535;
var resolution = 4;
var timer;
const startedAt = new Date().getTime();
module.exports = function(seconds) {
var size = resolution * (seconds || 5);
var buffer = [0];
var pointer = 1;
var last = (tick - 1) & maxTick;
var inc = function() {
tick = (tick + 1) & maxTick;
console.log(`$ ${new Date().getTime() - startedAt}ms passed. buffer ${buffer}`);
};
if (!timer) {
timer = setInterval(inc, (1000 / resolution) | 0);
if (timer.unref) timer.unref();
}
console.log(`$ ${new Date().getTime() - startedAt}ms passed. buffer ${buffer}`);
return function(delta) {
var dist = (tick - last) & maxTick;
if (dist > size) dist = size;
last = tick;
while (dist--) {
if (pointer === size) pointer = 0;
buffer[pointer] = buffer[pointer === 0 ? size - 1 : pointer - 1];
pointer++;
}
if (delta) buffer[pointer - 1] += delta;
var top = buffer[pointer - 1];
var btm = buffer.length < size ? 0 : buffer[pointer === size ? 0 : pointer];
console.log(
`$ ${new Date().getTime() -
startedAt}ms passed. buffer ${buffer} top ${top} top index ${pointer -
1} btm ${btm} btm index ${buffer.length < size ? 'null' : pointer === size ? 0 : pointer}`,
`value ${buffer.length < resolution ? top : ((top - btm) * resolution) / buffer.length}`,
);
return buffer.length < resolution ? top : ((top - btm) * resolution) / buffer.length;
};
};
// Hi - thanks for taking the time to read this code.
// It uses a regular sliding window that is updated (per default every 1/4th second)
// Basically there is a an array that has size buffer-this-many-seconds * 4 (the default is 5s)
// and two pointers top and btm that points to the newest entry in this buffer and the oldest one.
// Every 1/4th second the top pointer is incremented and if it is bigger than the array is it reset to 0.
// When top === btm we increment btm as well (as the oldest entry is now outdated).
// When ever you update the speedometer with a delta value we increment array[top] with this value and when the top pointer is incremented we copy the value to the new top entry.
// To calculate the speed we now just need to (array[top] - array[btm]) / 5 since that gives us the delta speed in the last 5s.
const speedometer = require('./speedometer');
const speed = speedometer(2);
setTimeout(() => {
speed(3);
speed(3);
setTimeout(() => {
speed(1);
}, 300);
setTimeout(() => {
speed(0);
}, 500);
setTimeout(() => {
speed(2);
}, 400);
setTimeout(() => {
speed(3);
speed(3);
setTimeout(() => {
speed(1);
}, 300);
setTimeout(() => {
speed(0);
}, 500);
setTimeout(() => {
speed(2);
}, 400);
}, 500);
setTimeout(() => {
speed(0);
}, 2100);
setTimeout(() => {
speed(0);
}, 2500);
}, 2050);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment