From 7f5e0cb49370072a19faefe492f8cb95e59f1818 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 21 Nov 2016 20:37:23 -0800 Subject: [PATCH] writer: improve perf. --- lib/utils/writer.js | 143 +++++++++++++++++++++++++------------------- 1 file changed, 81 insertions(+), 62 deletions(-) diff --git a/lib/utils/writer.js b/lib/utils/writer.js index 3ab86687..dd20d107 100644 --- a/lib/utils/writer.js +++ b/lib/utils/writer.js @@ -63,7 +63,7 @@ function BufferWriter(options) { if (!(this instanceof BufferWriter)) return new BufferWriter(options); - this.data = []; + this.ops = []; this.written = 0; } @@ -76,40 +76,40 @@ function BufferWriter(options) { BufferWriter.prototype.render = function render(keep) { var data = new Buffer(this.written); var off = 0; - var i, item; + var i, op; - for (i = 0; i < this.data.length; i++) { - item = this.data[i]; - switch (item[0]) { - case SEEK: off += item[1]; break; - case UI8: off = data.writeUInt8(item[1], off, true); break; - case UI16: off = data.writeUInt16LE(item[1], off, true); break; - case UI16BE: off = data.writeUInt16BE(item[1], off, true); break; - case UI32: off = data.writeUInt32LE(item[1], off, true); break; - case UI32BE: off = data.writeUInt32BE(item[1], off, true); break; - case UI64: off = encoding.writeU64(data, item[1], off); break; - case UI64BE: off = encoding.writeU64BE(data, item[1], off); break; - case I8: off = data.writeInt8(item[1], off, true); break; - case I16: off = data.writeInt16LE(item[1], off, true); break; - case I16BE: off = data.writeInt16BE(item[1], off, true); break; - case I32: off = data.writeInt32LE(item[1], off, true); break; - case I32BE: off = data.writeInt32BE(item[1], off, true); break; - case I64: off = encoding.write64(data, item[1], off); break; - case I64BE: off = encoding.write64BE(data, item[1], off); break; - case FL: off = data.writeFloatLE(item[1], off, true); break; - case FLBE: off = data.writeFloatBE(item[1], off, true); break; - case DBL: off = data.writeDoubleLE(item[1], off, true); break; - case DBLBE: off = data.writeDoubleBE(item[1], off, true); break; - case VARINT: off = encoding.writeVarint(data, item[1], off); break; - case VARINT2: off = encoding.writeVarint2(data, item[1], off); break; - case BYTES: off += item[1].copy(data, off); break; - case STR: off += data.write(item[1], off, item[2]); break; + for (i = 0; i < this.ops.length; i++) { + op = this.ops[i]; + switch (op.type) { + case SEEK: off += op.value; break; + case UI8: off = data.writeUInt8(op.value, off, true); break; + case UI16: off = data.writeUInt16LE(op.value, off, true); break; + case UI16BE: off = data.writeUInt16BE(op.value, off, true); break; + case UI32: off = data.writeUInt32LE(op.value, off, true); break; + case UI32BE: off = data.writeUInt32BE(op.value, off, true); break; + case UI64: off = encoding.writeU64(data, op.value, off); break; + case UI64BE: off = encoding.writeU64BE(data, op.value, off); break; + case I8: off = data.writeInt8(op.value, off, true); break; + case I16: off = data.writeInt16LE(op.value, off, true); break; + case I16BE: off = data.writeInt16BE(op.value, off, true); break; + case I32: off = data.writeInt32LE(op.value, off, true); break; + case I32BE: off = data.writeInt32BE(op.value, off, true); break; + case I64: off = encoding.write64(data, op.value, off); break; + case I64BE: off = encoding.write64BE(data, op.value, off); break; + case FL: off = data.writeFloatLE(op.value, off, true); break; + case FLBE: off = data.writeFloatBE(op.value, off, true); break; + case DBL: off = data.writeDoubleLE(op.value, off, true); break; + case DBLBE: off = data.writeDoubleBE(op.value, off, true); break; + case VARINT: off = encoding.writeVarint(data, op.value, off); break; + case VARINT2: off = encoding.writeVarint2(data, op.value, off); break; + case BYTES: off += op.value.copy(data, off); break; + case STR: off += data.write(op.value, off, op.enc); break; case CHECKSUM: off += crypto.hash256(data.slice(0, off)).copy(data, off, 0, 4); break; case FILL: - data.fill(item[1], off, off + item[2]); - off += item[2]; + data.fill(op.value, off, off + op.size); + off += op.size; break; default: assert(false, 'Bad type.'); @@ -140,16 +140,17 @@ BufferWriter.prototype.getSize = function getSize() { */ BufferWriter.prototype.seek = function seek(offset) { - this.data.push([SEEK, offset]); + this.written += offset; + this.ops.push(new WriteOp(SEEK, offset)); }; /** - * Destroy the buffer writer. Remove references to `data`. + * Destroy the buffer writer. Remove references to `ops`. */ BufferWriter.prototype.destroy = function destroy() { - this.data.length = 0; - this.data = null; + this.ops.length = 0; + this.ops = null; this.written = null; }; @@ -160,7 +161,7 @@ BufferWriter.prototype.destroy = function destroy() { BufferWriter.prototype.writeU8 = function writeU8(value) { this.written += 1; - this.data.push([UI8, value]); + this.ops.push(new WriteOp(UI8, value)); }; /** @@ -170,7 +171,7 @@ BufferWriter.prototype.writeU8 = function writeU8(value) { BufferWriter.prototype.writeU16 = function writeU16(value) { this.written += 2; - this.data.push([UI16, value]); + this.ops.push(new WriteOp(UI16, value)); }; /** @@ -180,7 +181,7 @@ BufferWriter.prototype.writeU16 = function writeU16(value) { BufferWriter.prototype.writeU16BE = function writeU16BE(value) { this.written += 2; - this.data.push([UI16BE, value]); + this.ops.push(new WriteOp(UI16BE, value)); }; /** @@ -190,7 +191,7 @@ BufferWriter.prototype.writeU16BE = function writeU16BE(value) { BufferWriter.prototype.writeU32 = function writeU32(value) { this.written += 4; - this.data.push([UI32, value]); + this.ops.push(new WriteOp(UI32, value)); }; /** @@ -200,7 +201,7 @@ BufferWriter.prototype.writeU32 = function writeU32(value) { BufferWriter.prototype.writeU32BE = function writeU32BE(value) { this.written += 4; - this.data.push([UI32BE, value]); + this.ops.push(new WriteOp(UI32BE, value)); }; /** @@ -210,7 +211,7 @@ BufferWriter.prototype.writeU32BE = function writeU32BE(value) { BufferWriter.prototype.writeU64 = function writeU64(value) { this.written += 8; - this.data.push([UI64, value]); + this.ops.push(new WriteOp(UI64, value)); }; /** @@ -220,7 +221,7 @@ BufferWriter.prototype.writeU64 = function writeU64(value) { BufferWriter.prototype.writeU64BE = function writeU64BE(value) { this.written += 8; - this.data.push([UI64BE, value]); + this.ops.push(new WriteOp(UI64BE, value)); }; /** @@ -230,7 +231,7 @@ BufferWriter.prototype.writeU64BE = function writeU64BE(value) { BufferWriter.prototype.write8 = function write8(value) { this.written += 1; - this.data.push([I8, value]); + this.ops.push(new WriteOp(I8, value)); }; /** @@ -240,7 +241,7 @@ BufferWriter.prototype.write8 = function write8(value) { BufferWriter.prototype.write16 = function write16(value) { this.written += 2; - this.data.push([I16, value]); + this.ops.push(new WriteOp(I16, value)); }; /** @@ -250,7 +251,7 @@ BufferWriter.prototype.write16 = function write16(value) { BufferWriter.prototype.write16BE = function write16BE(value) { this.written += 2; - this.data.push([I16BE, value]); + this.ops.push(new WriteOp(I16BE, value)); }; /** @@ -260,7 +261,7 @@ BufferWriter.prototype.write16BE = function write16BE(value) { BufferWriter.prototype.write32 = function write32(value) { this.written += 4; - this.data.push([I32, value]); + this.ops.push(new WriteOp(I32, value)); }; /** @@ -270,7 +271,7 @@ BufferWriter.prototype.write32 = function write32(value) { BufferWriter.prototype.write32BE = function write32BE(value) { this.written += 4; - this.data.push([I32BE, value]); + this.ops.push(new WriteOp(I32BE, value)); }; /** @@ -280,7 +281,7 @@ BufferWriter.prototype.write32BE = function write32BE(value) { BufferWriter.prototype.write64 = function write64(value) { this.written += 8; - this.data.push([I64, value]); + this.ops.push(new WriteOp(I64, value)); }; /** @@ -290,7 +291,7 @@ BufferWriter.prototype.write64 = function write64(value) { BufferWriter.prototype.write64BE = function write64BE(value) { this.written += 8; - this.data.push([I64BE, value]); + this.ops.push(new WriteOp(I64BE, value)); }; /** @@ -300,7 +301,7 @@ BufferWriter.prototype.write64BE = function write64BE(value) { BufferWriter.prototype.writeFloat = function writeFloat(value) { this.written += 4; - this.data.push([FL, value]); + this.ops.push(new WriteOp(FL, value)); }; /** @@ -310,7 +311,7 @@ BufferWriter.prototype.writeFloat = function writeFloat(value) { BufferWriter.prototype.writeFloatBE = function writeFloatBE(value) { this.written += 4; - this.data.push([FLBE, value]); + this.ops.push(new WriteOp(FLBE, value)); }; /** @@ -320,7 +321,7 @@ BufferWriter.prototype.writeFloatBE = function writeFloatBE(value) { BufferWriter.prototype.writeDouble = function writeDouble(value) { this.written += 8; - this.data.push([DBL, value]); + this.ops.push(new WriteOp(DBL, value)); }; /** @@ -330,7 +331,7 @@ BufferWriter.prototype.writeDouble = function writeDouble(value) { BufferWriter.prototype.writeDoubleBE = function writeDoubleBE(value) { this.written += 8; - this.data.push([DBLBE, value]); + this.ops.push(new WriteOp(DBLBE, value)); }; /** @@ -345,7 +346,7 @@ BufferWriter.prototype.writeVarint = function writeVarint(value) { assert(!value.isNeg()); this.written += encoding.sizeVarint(value); - this.data.push([VARINT, value]); + this.ops.push(new WriteOp(VARINT, value)); }; /** @@ -360,7 +361,7 @@ BufferWriter.prototype.writeVarint2 = function writeVarint2(value) { assert(!value.isNeg()); this.written += encoding.sizeVarint2(value); - this.data.push([VARINT2, value]); + this.ops.push(new WriteOp(VARINT2, value)); }; /** @@ -369,8 +370,11 @@ BufferWriter.prototype.writeVarint2 = function writeVarint2(value) { */ BufferWriter.prototype.writeBytes = function writeBytes(value) { + if (value.length === 0) + return; + this.written += value.length; - this.data.push([BYTES, value]); + this.ops.push(new WriteOp(BYTES, value)); }; /** @@ -380,9 +384,13 @@ BufferWriter.prototype.writeBytes = function writeBytes(value) { BufferWriter.prototype.writeVarBytes = function writeVarBytes(value) { this.written += encoding.sizeVarint(value.length); + this.ops.push(new WriteOp(VARINT, value.length)); + + if (value.length === 0) + return; + this.written += value.length; - this.data.push([VARINT, value.length]); - this.data.push([BYTES, value]); + this.ops.push(new WriteOp(BYTES, value)); }; /** @@ -400,7 +408,7 @@ BufferWriter.prototype.writeString = function writeString(value, enc) { if (value.length === 0) return; - this.data.push([STR, value, enc]); + this.ops.push(new WriteOp(STR, value, enc)); }; /** @@ -429,12 +437,12 @@ BufferWriter.prototype.writeVarString = function writeVarString(value, enc) { this.written += encoding.sizeVarint(size); this.written += size; - this.data.push([VARINT, size]); + this.ops.push(new WriteOp(VARINT, size)); if (value.length === 0) return; - this.data.push([STR, value, enc]); + this.ops.push(new WriteOp(STR, value, enc)); }; /** @@ -454,7 +462,7 @@ BufferWriter.prototype.writeNullString = function writeNullString(value, enc) { BufferWriter.prototype.writeChecksum = function writeChecksum() { this.written += 4; - this.data.push([CHECKSUM]); + this.ops.push(new WriteOp(CHECKSUM)); }; /** @@ -470,9 +478,20 @@ BufferWriter.prototype.fill = function fill(value, size) { return; this.written += size; - this.data.push([FILL, value, size]); + this.ops.push(new WriteOp(FILL, value, null, size)); }; +/* + * Helpers + */ + +function WriteOp(type, value, enc, size) { + this.type = type; + this.value = value; + this.enc = enc; + this.size = size; +} + /* * Expose */