| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 2c63d30 commit e2f03c8
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,7 +4,7 @@ const common = require('../common'); | |||
| 4 | 4 | const bench = common.createBenchmark(main, { | |
| 5 | 5 | type: ['one_byte', 'two_bytes', 'three_bytes', | |
| 6 | 6 | 'four_bytes', 'latin1'], | |
| 7 | - encoding: ['utf8', 'base64'], | ||
| 7 | + encoding: ['utf8', 'base64', 'latin1', 'hex'], | ||
| 8 | 8 | repeat: [1, 2, 16, 256], // x16 | |
| 9 | 9 | n: [4e6], | |
| 10 | 10 | }); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,31 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common.js'); | ||
| 4 | + | ||
| 5 | + const bench = common.createBenchmark(main, { | ||
| 6 | + type: ['Uint8Array', 'Uint16Array', 'Uint32Array', 'Float64Array'], | ||
| 7 | + len: [64, 256, 2048], | ||
| 8 | + partial: ['none', 'offset', 'offset-length'], | ||
| 9 | + n: [6e5], | ||
| 10 | + }); | ||
| 11 | + | ||
| 12 | + function main({ n, len, type, partial }) { | ||
| 13 | + const TypedArrayCtor = globalThis[type]; | ||
| 14 | + const src = new TypedArrayCtor(len); | ||
| 15 | + for (let i = 0; i < len; i++) src[i] = i; | ||
| 16 | + | ||
| 17 | + let offset; | ||
| 18 | + let length; | ||
| 19 | + if (partial === 'offset') { | ||
| 20 | + offset = len >>> 2; | ||
| 21 | + } else if (partial === 'offset-length') { | ||
| 22 | + offset = len >>> 2; | ||
| 23 | + length = len >>> 1; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + bench.start(); | ||
| 27 | + for (let i = 0; i < n; i++) { | ||
| 28 | + Buffer.copyBytesFrom(src, offset, length); | ||
| 29 | + } | ||
| 30 | + bench.end(n); | ||
| 31 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,7 @@ const bench = common.createBenchmark(main, { | |||
| 10 | 10 | 'fill("t")', | |
| 11 | 11 | 'fill("test")', | |
| 12 | 12 | 'fill("t", "utf8")', | |
| 13 | + 'fill("t", "ascii")', | ||
| 13 | 14 | 'fill("t", 0, "utf8")', | |
| 14 | 15 | 'fill("t", 0)', | |
| 15 | 16 | 'fill(Buffer.alloc(1), 0)', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,7 +19,7 @@ const searchStrings = [ | |||
| 19 | 19 | ||
| 20 | 20 | const bench = common.createBenchmark(main, { | |
| 21 | 21 | search: searchStrings, | |
| 22 | - encoding: ['undefined', 'utf8', 'ucs2', 'latin1'], | ||
| 22 | + encoding: ['undefined', 'utf8', 'ascii', 'latin1', 'ucs2'], | ||
| 23 | 23 | type: ['buffer', 'string'], | |
| 24 | 24 | n: [5e4], | |
| 25 | 25 | }, { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,7 +3,7 @@ | |||
| 3 | 3 | const common = require('../common.js'); | |
| 4 | 4 | ||
| 5 | 5 | const bench = common.createBenchmark(main, { | |
| 6 | - encoding: ['', 'utf8', 'ascii', 'latin1', 'hex', 'UCS-2'], | ||
| 6 | + encoding: ['', 'utf8', 'ascii', 'latin1', 'hex', 'base64', 'base64url', 'UCS-2'], | ||
| 7 | 7 | args: [0, 1, 3], | |
| 8 | 8 | len: [1, 64, 1024], | |
| 9 | 9 | n: [1e6], | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -50,7 +50,6 @@ const { | |||
| 50 | 50 | TypedArrayPrototypeGetByteOffset, | |
| 51 | 51 | TypedArrayPrototypeGetLength, | |
| 52 | 52 | TypedArrayPrototypeSet, | |
| 53 | - TypedArrayPrototypeSlice, | ||
| 54 | 53 | TypedArrayPrototypeSubarray, | |
| 55 | 54 | Uint8Array, | |
| 56 | 55 | } = primordials; | |
@@ -383,28 +382,33 @@ Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) { | |||
| 383 | 382 | return new FastBuffer(); | |
| 384 | 383 | } | |
| 385 | 384 | ||
| 386 | - if (offset !== undefined || length !== undefined) { | ||
| 387 | - if (offset !== undefined) { | ||
| 388 | - validateInteger(offset, 'offset', 0); | ||
| 389 | - if (offset >= viewLength) return new FastBuffer(); | ||
| 390 | - } else { | ||
| 391 | - offset = 0; | ||
| 392 | - } | ||
| 393 | - let end; | ||
| 394 | - if (length !== undefined) { | ||
| 395 | - validateInteger(length, 'length', 0); | ||
| 396 | - end = offset + length; | ||
| 397 | - } else { | ||
| 398 | - end = viewLength; | ||
| 399 | - } | ||
| 385 | + let start = 0; | ||
| 386 | + let end = viewLength; | ||
| 400 | 387 | ||
| 401 | - view = TypedArrayPrototypeSlice(view, offset, end); | ||
| 388 | + if (offset !== undefined) { | ||
| 389 | + validateInteger(offset, 'offset', 0); | ||
| 390 | + if (offset >= viewLength) return new FastBuffer(); | ||
| 391 | + start = offset; | ||
| 402 | 392 | } | |
| 403 | 393 | ||
| 394 | + if (length !== undefined) { | ||
| 395 | + validateInteger(length, 'length', 0); | ||
| 396 | + // The old code used TypedArrayPrototypeSlice which clamps internally. | ||
| 397 | + end = MathMin(start + length, viewLength); | ||
| 398 | + } | ||
| 399 | + | ||
| 400 | + if (end <= start) return new FastBuffer(); | ||
| 401 | + | ||
| 402 | + const viewByteLength = TypedArrayPrototypeGetByteLength(view); | ||
| 403 | + const elementSize = viewByteLength / viewLength; | ||
| 404 | + const srcByteOffset = TypedArrayPrototypeGetByteOffset(view) + | ||
| 405 | + start * elementSize; | ||
| 406 | + const srcByteLength = (end - start) * elementSize; | ||
| 407 | + | ||
| 404 | 408 | return fromArrayLike(new Uint8Array( | |
| 405 | 409 | TypedArrayPrototypeGetBuffer(view), | |
| 406 | - TypedArrayPrototypeGetByteOffset(view), | ||
| 407 | - TypedArrayPrototypeGetByteLength(view))); | ||
| 410 | + srcByteOffset, | ||
| 411 | + srcByteLength)); | ||
| 408 | 412 | }; | |
| 409 | 413 | ||
| 410 | 414 | // Identical to the built-in %TypedArray%.of(), but avoids using the deprecated | |
@@ -551,14 +555,15 @@ function fromArrayBuffer(obj, byteOffset, length) { | |||
| 551 | 555 | } | |
| 552 | 556 | ||
| 553 | 557 | function fromArrayLike(obj) { | |
| 554 | - if (obj.length <= 0) | ||
| 558 | + const { length } = obj; | ||
| 559 | + if (length <= 0) | ||
| 555 | 560 | return new FastBuffer(); | |
| 556 | - if (obj.length < (Buffer.poolSize >>> 1)) { | ||
| 557 | - if (obj.length > (poolSize - poolOffset)) | ||
| 561 | + if (length < (Buffer.poolSize >>> 1)) { | ||
| 562 | + if (length > (poolSize - poolOffset)) | ||
| 558 | 563 | createPool(); | |
| 559 | - const b = new FastBuffer(allocPool, poolOffset, obj.length); | ||
| 564 | + const b = new FastBuffer(allocPool, poolOffset, length); | ||
| 560 | 565 | TypedArrayPrototypeSet(b, obj, 0); | |
| 561 | - poolOffset += obj.length; | ||
| 566 | + poolOffset += length; | ||
| 562 | 567 | alignPool(); | |
| 563 | 568 | return b; | |
| 564 | 569 | } | |
@@ -732,11 +737,7 @@ const encodingOps = { | |||
| 732 | 737 | write: asciiWrite, | |
| 733 | 738 | slice: asciiSlice, | |
| 734 | 739 | indexOf: (buf, val, byteOffset, dir) => | |
| 735 | - indexOfBuffer(buf, | ||
| 736 | - fromStringFast(val, encodingOps.ascii), | ||
| 737 | - byteOffset, | ||
| 738 | - encodingsMap.ascii, | ||
| 739 | - dir), | ||
| 740 | + indexOfString(buf, val, byteOffset, encodingsMap.ascii, dir), | ||
| 740 | 741 | }, | |
| 741 | 742 | base64: { | |
| 742 | 743 | encoding: 'base64', | |
@@ -897,17 +898,17 @@ Buffer.prototype.toString = function toString(encoding, start, end) { | |||
| 897 | 898 | return utf8Slice(this, 0, this.length); | |
| 898 | 899 | } | |
| 899 | 900 | ||
| 900 | - const len = this.length; | ||
| 901 | + const bufferLength = TypedArrayPrototypeGetLength(this); | ||
| 901 | 902 | ||
| 902 | 903 | if (start <= 0) | |
| 903 | 904 | start = 0; | |
| 904 | - else if (start >= len) | ||
| 905 | + else if (start >= bufferLength) | ||
| 905 | 906 | return ''; | |
| 906 | 907 | else | |
| 907 | 908 | start = MathTrunc(start) || 0; | |
| 908 | 909 | ||
| 909 | - if (end === undefined || end > len) | ||
| 910 | - end = len; | ||
| 910 | + if (end === undefined || end > bufferLength) | ||
| 911 | + end = bufferLength; | ||
| 911 | 912 | else | |
| 912 | 913 | end = MathTrunc(end) || 0; | |
| 913 | 914 | ||
@@ -1118,7 +1119,9 @@ function _fill(buf, value, offset, end, encoding) { | |||
| 1118 | 1119 | value = 0; | |
| 1119 | 1120 | } else if (value.length === 1) { | |
| 1120 | 1121 | // Fast path: If `value` fits into a single byte, use that numeric value. | |
| 1121 | - if (normalizedEncoding === 'utf8') { | ||
| 1122 | + // ASCII shares this branch with utf8 since code < 128 covers the full | ||
| 1123 | + // ASCII range; anything outside falls through to C++ bindingFill. | ||
| 1124 | + if (normalizedEncoding === 'utf8' || normalizedEncoding === 'ascii') { | ||
| 1122 | 1125 | const code = StringPrototypeCharCodeAt(value, 0); | |
| 1123 | 1126 | if (code < 128) { | |
| 1124 | 1127 | value = code; | |
@@ -1168,29 +1171,30 @@ function _fill(buf, value, offset, end, encoding) { | |||
| 1168 | 1171 | } | |
| 1169 | 1172 | ||
| 1170 | 1173 | Buffer.prototype.write = function write(string, offset, length, encoding) { | |
| 1174 | + const bufferLength = TypedArrayPrototypeGetLength(this); | ||
| 1171 | 1175 | // Buffer#write(string); | |
| 1172 | 1176 | if (offset === undefined) { | |
| 1173 | - return utf8Write(this, string, 0, this.length); | ||
| 1177 | + return utf8Write(this, string, 0, bufferLength); | ||
| 1174 | 1178 | } | |
| 1175 | 1179 | // Buffer#write(string, encoding) | |
| 1176 | 1180 | if (length === undefined && typeof offset === 'string') { | |
| 1177 | 1181 | encoding = offset; | |
| 1178 | - length = this.length; | ||
| 1182 | + length = bufferLength; | ||
| 1179 | 1183 | offset = 0; | |
| 1180 | 1184 | ||
| 1181 | 1185 | // Buffer#write(string, offset[, length][, encoding]) | |
| 1182 | 1186 | } else { | |
| 1183 | - validateOffset(offset, 'offset', 0, this.length); | ||
| 1187 | + validateOffset(offset, 'offset', 0, bufferLength); | ||
| 1184 | 1188 | ||
| 1185 | - const remaining = this.length - offset; | ||
| 1189 | + const remaining = bufferLength - offset; | ||
| 1186 | 1190 | ||
| 1187 | 1191 | if (length === undefined) { | |
| 1188 | 1192 | length = remaining; | |
| 1189 | 1193 | } else if (typeof length === 'string') { | |
| 1190 | 1194 | encoding = length; | |
| 1191 | 1195 | length = remaining; | |
| 1192 | 1196 | } else { | |
| 1193 | - validateOffset(length, 'length', 0, this.length); | ||
| 1197 | + validateOffset(length, 'length', 0, bufferLength); | ||
| 1194 | 1198 | if (length > remaining) | |
| 1195 | 1199 | length = remaining; | |
| 1196 | 1200 | } | |
@@ -1208,9 +1212,10 @@ Buffer.prototype.write = function write(string, offset, length, encoding) { | |||
| 1208 | 1212 | }; | |
| 1209 | 1213 | ||
| 1210 | 1214 | Buffer.prototype.toJSON = function toJSON() { | |
| 1211 | - if (this.length > 0) { | ||
| 1212 | - const data = new Array(this.length); | ||
| 1213 | - for (let i = 0; i < this.length; ++i) | ||
| 1215 | + const bufferLength = TypedArrayPrototypeGetLength(this); | ||
| 1216 | + if (bufferLength > 0) { | ||
| 1217 | + const data = new Array(bufferLength); | ||
| 1218 | + for (let i = 0; i < bufferLength; ++i) | ||
| 1214 | 1219 | data[i] = this[i]; | |
| 1215 | 1220 | return { type: 'Buffer', data }; | |
| 1216 | 1221 | } | |
@@ -1235,7 +1240,7 @@ function adjustOffset(offset, length) { | |||
| 1235 | 1240 | } | |
| 1236 | 1241 | ||
| 1237 | 1242 | Buffer.prototype.subarray = function subarray(start, end) { | |
| 1238 | - const srcLength = this.length; | ||
| 1243 | + const srcLength = TypedArrayPrototypeGetLength(this); | ||
| 1239 | 1244 | start = adjustOffset(start, srcLength); | |
| 1240 | 1245 | end = end !== undefined ? adjustOffset(end, srcLength) : srcLength; | |
| 1241 | 1246 | const newLength = end > start ? end - start : 0; | |
@@ -1253,45 +1258,52 @@ function swap(b, n, m) { | |||
| 1253 | 1258 | } | |
| 1254 | 1259 | ||
| 1255 | 1260 | Buffer.prototype.swap16 = function swap16() { | |
| 1256 | - // For Buffer.length < 128, it's generally faster to | ||
| 1261 | + // Ref: https://github.com/nodejs/node/pull/61871#discussion_r2889557696 | ||
| 1262 | + // For Buffer.length <= 32, it's generally faster to | ||
| 1257 | 1263 | // do the swap in javascript. For larger buffers, | |
| 1258 | 1264 | // dropping down to the native code is faster. | |
| 1259 | - const len = this.length; | ||
| 1265 | + const len = TypedArrayPrototypeGetLength(this); | ||
| 1260 | 1266 | if (len % 2 !== 0) | |
| 1261 | 1267 | throw new ERR_INVALID_BUFFER_SIZE('16-bits'); | |
| 1262 | - if (len < 128) { | ||
| 1268 | + if (len <= 32) { | ||
| 1263 | 1269 | for (let i = 0; i < len; i += 2) | |
| 1264 | 1270 | swap(this, i, i + 1); | |
| 1265 | 1271 | return this; | |
| 1266 | 1272 | } | |
| 1267 | - return _swap16(this); | ||
| 1273 | + _swap16(this); | ||
| 1274 | + return this; | ||
| 1268 | 1275 | }; | |
| 1269 | 1276 | ||
| 1270 | 1277 | Buffer.prototype.swap32 = function swap32() { | |
| 1271 | - // For Buffer.length < 192, it's generally faster to | ||
| 1278 | + // Ref: https://github.com/nodejs/node/pull/61871#discussion_r2889557696 | ||
| 1279 | + // For Buffer.length <= 32, it's generally faster to | ||
| 1272 | 1280 | // do the swap in javascript. For larger buffers, | |
| 1273 | 1281 | // dropping down to the native code is faster. | |
| 1274 | - const len = this.length; | ||
| 1282 | + const len = TypedArrayPrototypeGetLength(this); | ||
| 1275 | 1283 | if (len % 4 !== 0) | |
| 1276 | 1284 | throw new ERR_INVALID_BUFFER_SIZE('32-bits'); | |
| 1277 | - if (len < 192) { | ||
| 1285 | + if (len <= 32) { | ||
| 1278 | 1286 | for (let i = 0; i < len; i += 4) { | |
| 1279 | 1287 | swap(this, i, i + 3); | |
| 1280 | 1288 | swap(this, i + 1, i + 2); | |
| 1281 | 1289 | } | |
| 1282 | 1290 | return this; | |
| 1283 | 1291 | } | |
| 1284 | - return _swap32(this); | ||
| 1292 | + _swap32(this); | ||
| 1293 | + return this; | ||
| 1285 | 1294 | }; | |
| 1286 | 1295 | ||
| 1287 | 1296 | Buffer.prototype.swap64 = function swap64() { | |
| 1288 | - // For Buffer.length < 192, it's generally faster to | ||
| 1297 | + // Ref: https://github.com/nodejs/node/pull/61871#discussion_r2889557696 | ||
| 1298 | + // For Buffer.length < 48, it's generally faster to | ||
| 1289 | 1299 | // do the swap in javascript. For larger buffers, | |
| 1290 | 1300 | // dropping down to the native code is faster. | |
| 1291 | - const len = this.length; | ||
| 1301 | + // Threshold differs from swap16/swap32 (<=32) because swap64's | ||
| 1302 | + // crossover is between 40 and 48 (native wins at 48, loses at 40). | ||
| 1303 | + const len = TypedArrayPrototypeGetLength(this); | ||
| 1292 | 1304 | if (len % 8 !== 0) | |
| 1293 | 1305 | throw new ERR_INVALID_BUFFER_SIZE('64-bits'); | |
| 1294 | - if (len < 192) { | ||
| 1306 | + if (len < 48) { | ||
| 1295 | 1307 | for (let i = 0; i < len; i += 8) { | |
| 1296 | 1308 | swap(this, i, i + 7); | |
| 1297 | 1309 | swap(this, i + 1, i + 6); | |
@@ -1300,7 +1312,8 @@ Buffer.prototype.swap64 = function swap64() { | |||
| 1300 | 1312 | } | |
| 1301 | 1313 | return this; | |
| 1302 | 1314 | } | |
| 1303 | - return _swap64(this); | ||
| 1315 | + _swap64(this); | ||
| 1316 | + return this; | ||
| 1304 | 1317 | }; | |
| 1305 | 1318 | ||
| 1306 | 1319 | Buffer.prototype.toLocaleString = Buffer.prototype.toString; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments