<!--your preparation HTML code goes here-->
function serializeToArrayBuffer(obj) {
const encoder = new TextEncoder();
let bufferArray = [];
function serialize(value) {
if (typeof value === "string") {
bufferArray.push(1); // Type marker for string
const encoded = encoder.encode(value);
bufferArray.push(new Uint8Array(new Uint32Array([encoded.length]).buffer));
bufferArray.push(encoded);
} else if (typeof value === "number") {
bufferArray.push(2); // Type marker for number
bufferArray.push(new Uint8Array(new Float64Array([value]).buffer));
} else if (typeof value === "boolean") {
bufferArray.push(3); // Type marker for boolean
bufferArray.push(value ? 1 : 0);
} else if (Array.isArray(value)) {
bufferArray.push(4); // Type marker for array
bufferArray.push(new Uint8Array(new Uint32Array([value.length]).buffer));
value.forEach((item) => serialize(item));
} else if (value && typeof value === "object") {
bufferArray.push(5); // Type marker for object
const keys = Object.keys(value);
bufferArray.push(new Uint8Array(new Uint32Array([keys.length]).buffer));
keys.forEach((key) => {
serialize(key); // Serialize key as string
serialize(value[key]); // Serialize value
});
} else if (value === null) {
bufferArray.push(6); // Type marker for null
}
}
serialize(obj);
return new Uint8Array(bufferArray).buffer;
}
function deserializeFromArrayBuffer(buffer) {
const decoder = new TextDecoder();
const uint8Array = new Uint8Array(buffer);
let offset = 0;
function deserialize() {
const type = uint8Array[offset++];
if (type === 1) {
// String
const length = new Uint32Array(uint8Array.buffer.slice(offset, offset + 4))[0];
offset += 4;
const str = decoder.decode(uint8Array.slice(offset, offset + length));
offset += length;
return str;
} else if (type === 2) {
// Number
const num = new Float64Array(uint8Array.buffer.slice(offset, offset + 8))[0];
offset += 8;
return num;
} else if (type === 3) {
// Boolean
return uint8Array[offset++] === 1;
} else if (type === 4) {
// Array
const length = new Uint32Array(uint8Array.buffer.slice(offset, offset + 4))[0];
offset += 4;
const arr = [];
for (let i = 0; i < length; i++) {
arr.push(deserialize());
}
return arr;
} else if (type === 5) {
// Object
const length = new Uint32Array(uint8Array.buffer.slice(offset, offset + 4))[0];
offset += 4;
const obj = {};
for (let i = 0; i < length; i++) {
const key = deserialize(); // Deserialize key (string)
const value = deserialize(); // Deserialize value
obj[key] = value;
}
return obj;
} else if (type === 6) {
// Null
return null;
} else {
throw new Error("Unknown type marker: " + type);
}
}
return deserialize();
}
const test = {
a: "hohojoho",
b: { c: [1, "string", { nested: true }, null] },
d: 1,
e: true,
f: null,
};
const buffer = serializeToArrayBuffer(test);
const result = deserializeFromArrayBuffer(buffer);
const jsonStr = JSON.stringify(test);
const result = JSON.parse(jsonStr);
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
arraybuffer | |
json |
Test name | Executions per second |
---|---|
arraybuffer | 30950.8 Ops/sec |
json | 1657721.0 Ops/sec |
The benchmark under discussion compares two serialization methods to transform a JavaScript object into different formats: one using JSON serialization, and the other using a custom implementation based on ArrayBuffer. It evaluates the performance of these two approaches in terms of how many executions (or operations) can be completed per second.
ArrayBuffer Serialization
serializeToArrayBuffer
) which converts a JavaScript object into an ArrayBuffer. It identifies types such as strings, numbers, booleans, arrays, and objects, and uses type markers to facilitate deserialization.const buffer = serializeToArrayBuffer(test);
const result = deserializeFromArrayBuffer(buffer);
JSON Serialization
JSON.stringify()
to convert the object into a JSON string and then JSON.parse()
to convert it back to a JavaScript object.const jsonStr = JSON.stringify(test);
const result = JSON.parse(jsonStr);
Pros:
Cons:
Pros:
Cons:
From the benchmark results provided, we observe the following:
In conclusion, when choosing between these serialization methods, developers should consider the nature of their data, performance needs, ease of use, and ecosystem requirements, weighing the complexities against the benefits offered by each approach.