From b6702af1fc40ec68ae5f7b7b5b23dbed07fc4eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Louren=C3=A7o?= Date: Mon, 9 Oct 2023 23:28:46 -0300 Subject: [PATCH 1/3] lib: reduce overhead of blob clone --- benchmark/blob/clone.js | 7 +++++-- lib/internal/blob.js | 22 ++++++++++++---------- test/parallel/test-blob.js | 10 ++++++++++ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/benchmark/blob/clone.js b/benchmark/blob/clone.js index 7f66255ad9da0c..39890672fc66f8 100644 --- a/benchmark/blob/clone.js +++ b/benchmark/blob/clone.js @@ -7,14 +7,17 @@ const assert = require('assert'); const bench = common.createBenchmark(main, { n: [50e3], + bytes: [128, 1024, 1024 ** 2], }); let _cloneResult; -function main({ n }) { +function main({ n, bytes }) { + const buff = Buffer.allocUnsafe(bytes); + const blob = new Blob(buff); bench.start(); for (let i = 0; i < n; ++i) - _cloneResult = structuredClone(new Blob(['hello'])); + _cloneResult = structuredClone(blob); bench.end(n); // Avoid V8 deadcode (elimination) diff --git a/lib/internal/blob.js b/lib/internal/blob.js index a6801f3d7fba3b..314056ec140f04 100644 --- a/lib/internal/blob.js +++ b/lib/internal/blob.js @@ -200,7 +200,7 @@ class Blob { const length = this[kLength]; return { data: { handle, type, length }, - deserializeInfo: 'internal/blob:ClonedBlob', + deserializeInfo: 'internal/blob:CloneableBlob', }; } @@ -397,25 +397,27 @@ class Blob { } } -function ClonedBlob() { - return ReflectConstruct(function() { +class CloneableBlob extends Blob { + static { markTransferMode(this, true, false); - }, [], Blob); + this[kDeserialize] = () => {}; + } } -ClonedBlob.prototype[kDeserialize] = () => {}; -function TransferrableBlob(handle, length, type = '') { +CloneableBlob.prototype.constructor = Blob; + +function TransferableBlob(handle, length, type = '') { markTransferMode(this, true, false); this[kHandle] = handle; this[kType] = type; this[kLength] = length; } -ObjectSetPrototypeOf(TransferrableBlob.prototype, Blob.prototype); -ObjectSetPrototypeOf(TransferrableBlob, Blob); +ObjectSetPrototypeOf(TransferableBlob.prototype, Blob.prototype); +ObjectSetPrototypeOf(TransferableBlob, Blob); function createBlob(handle, length, type = '') { - const transferredBlob = new TransferrableBlob(handle, length, type); + const transferredBlob = new TransferableBlob(handle, length, type); // Fix issues like: https://github.com/nodejs/node/pull/49730#discussion_r1331720053 transferredBlob.constructor = Blob; @@ -489,7 +491,7 @@ function createBlobFromFilePath(path, options) { module.exports = { Blob, - ClonedBlob, + CloneableBlob, createBlob, createBlobFromFilePath, isBlob, diff --git a/test/parallel/test-blob.js b/test/parallel/test-blob.js index 04b0580202c171..cb9e2f239547f0 100644 --- a/test/parallel/test-blob.js +++ b/test/parallel/test-blob.js @@ -480,3 +480,13 @@ assert.throws(() => new Blob({}), { assert.ok(blob.slice(0, 1).constructor === Blob); assert.ok(blob.slice(0, 1) instanceof Blob); } + +(async () => { + const blob = new Blob(['hello']); + + assert.ok(structuredClone(blob).constructor === Blob); + assert.ok(structuredClone(blob) instanceof Blob); + assert.ok(structuredClone(blob).size === blob.size); + assert.ok(structuredClone(blob).size === blob.size); + assert.ok((await structuredClone(blob).text()) === (await blob.text())); +})().then(common.mustCall()); From 4bc72cb3e2745850f88edd78cdb008dded988d29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Louren=C3=A7o?= Date: Tue, 10 Oct 2023 23:07:53 -0300 Subject: [PATCH 2/3] fixup! lib: reduce overhead of blob clone --- lib/internal/blob.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/blob.js b/lib/internal/blob.js index 314056ec140f04..9b37bb37e87c51 100644 --- a/lib/internal/blob.js +++ b/lib/internal/blob.js @@ -8,7 +8,6 @@ const { ObjectDefineProperty, ObjectSetPrototypeOf, PromiseReject, - ReflectConstruct, RegExpPrototypeExec, RegExpPrototypeSymbolReplace, StringPrototypeToLowerCase, From ec65971c9ce02c91d6d2d2d46e608316c2eda36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Louren=C3=A7o?= Date: Sun, 15 Oct 2023 15:00:38 -0300 Subject: [PATCH 3/3] fixup! lib: reduce overhead of blob clone --- lib/internal/blob.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/lib/internal/blob.js b/lib/internal/blob.js index 9b37bb37e87c51..3ebb1b8a84b50a 100644 --- a/lib/internal/blob.js +++ b/lib/internal/blob.js @@ -199,7 +199,7 @@ class Blob { const length = this[kLength]; return { data: { handle, type, length }, - deserializeInfo: 'internal/blob:CloneableBlob', + deserializeInfo: 'internal/blob:Blob', }; } @@ -396,15 +396,6 @@ class Blob { } } -class CloneableBlob extends Blob { - static { - markTransferMode(this, true, false); - this[kDeserialize] = () => {}; - } -} - -CloneableBlob.prototype.constructor = Blob; - function TransferableBlob(handle, length, type = '') { markTransferMode(this, true, false); this[kHandle] = handle; @@ -490,7 +481,6 @@ function createBlobFromFilePath(path, options) { module.exports = { Blob, - CloneableBlob, createBlob, createBlobFromFilePath, isBlob,