Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Run results for:
Array Buffer vs JSON (use 1 DataVIew, use split instead of match)
Go to the benchmark
Embed
Embed Benchmark Result
Run details:
User agent:
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
Browser:
Chrome 128
Operating system:
Linux
Device Platform:
Desktop
Date tested:
one year ago
Test name
Executions per second
ArrayBuffer
5457.3 Ops/sec
JSON
8984.4 Ops/sec
Script Preparation code:
var cursors = Array.from({ length: 100 }, (_, i) => ({ type: `${Math.random() > 0.5 ? "presentation" : "whiteboard"}.cursor`, data: { id: btoa(`gid://stoege/${Math.random() > 0.5 ? "Pupil" : "Admin"}/${i%2 * 1000}`), aCoords: { tl: { x: Math.ceil(Math.random() * 1920), y: Math.ceil(Math.random() * 1080) } } } })); class BiderectionalMap { constructor() { this.keyToValue = new Map(); this.valueToKey = new Map(); } set(key, value) { if (this.keyToValue.has(key)) { const oldValue = this.keyToValue.get(key); this.valueToKey.delete(oldValue); } if (this.valueToKey.has(value)) { const oldKey = this.valueToKey.get(value); this.keyToValue.delete(oldKey); } this.keyToValue.set(key, value); this.valueToKey.set(value, key); } get(input) { if (typeof input === "number" && this.keyToValue.has(input)) { return this.keyToValue.get(input); } else if (typeof input === "string" && this.valueToKey.has(input)) { return this.valueToKey.get(input); } else { return undefined; } } } var eventTypes = new BiderectionalMap(); eventTypes.set(0, "undefined"); eventTypes.set(1, "presentation.cursor"); eventTypes.set(2, "whiteboard.cursor"); function rolesKV(key){ switch(key){ case 1: return "Admin"; case 2: return "Pupil"; default: return "undefined"; } }; function rolesVK(value){ switch(value){ case "Admin": return 1; case "Pupil": return 2; default: return 0; } }; const _madIdExtractor = (decodedId) => { const splitedStr = decodedId.split('/'); return [decodedId, splitedStr[3], splitedStr[4]]; }; const get_m_madIdExtractor = () => { const results = new Map(); return (decodedId) => { if (results.has(decodedId)) return results.get(decodedId); results.set(decodedId, _madIdExtractor(decodedId)); return results.get(decodedId); }; }; var m_atob = get_m_atob(); var m_btoa = get_m_btoa(); var m_madIdExtractor = get_m_madIdExtractor(); function crazyCompressor(cursor){ /* Bytes Bits Max Value 1 8 256 — Role 2 16 65,536 — X and Y 4 32 4,294,967,296 — ID 1 + 2 + 2 + 4 + 1 = 10 Role + X + Y + ID + Type */ const MAX_UINT32_VALUE = 4294967296; const buffer = new ArrayBuffer(10); const fullView = new DataView(buffer, 0, 10); const getId = (encodedId) => { const extractedId = m_madIdExtractor(m_atob(encodedId)); if (extractedId.length < 3) throw new Error("Incorrect id format"); const [_, role, rawId] = extractedId; const id = Number(rawId); if (id > MAX_UINT32_VALUE - 1) throw new Error("ID is bigger than max uint32 value"); return [role, id]; }; const getXY = (coords) => { const { x, y } = coords.tl; return [x, y]; }; const [role, id] = getId(cursor.data.id); const [x, y] = getXY(cursor.data.aCoords); fullView.setUint8(0, rolesVK(role)); fullView.setUint32(1, id); fullView.setUint16(5, x); fullView.setUint16(7, y); fullView.setUint8(9, eventTypes.get(cursor.type)); return buffer; }; function crazyDecompressor(buffer){ const fullView = new DataView(buffer, 0, 10); return { type: eventTypes.get(fullView.getUint8(0)), data: { id: m_btoa(`gid://stoege/${rolesKV(fullView.getUint8(9))}/${fullView.getUint32(1)}`), aCoords: { tl: { x: fullView.getUint16(5), y: fullView.getUint16(7) } } } }; }; function get_m_atob() { const results = new Map(); return (encodedString) => { if (results.has(encodedString)) return results.get(encodedString); results.set(encodedString, atob(encodedString)); return results.get(encodedString); }; } function get_m_btoa() { const results = new Map(); return (decodedString) => { if (results.has(decodedString)) return results.get(decodedString); results.set(decodedString, btoa(decodedString)); return results.get(decodedString); }; } function JSONCompressor(cursor) { return JSON.stringify(cursor); }; function JSONDecompressor(cursorStr) { return JSON.parse(cursorStr); };
Tests:
ArrayBuffer
const compressed = cursors.map(crazyCompressor); const decompressed = compressed.map(crazyDecompressor);
JSON
const compressed = cursors.map(JSONCompressor); const decompressed = compressed.map(JSONDecompressor);