Created
April 13, 2022 20:59
-
-
Save generalmimon/866bd57f98c227bcbba1e9834e225072 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* SPDX-FileCopyrightText: 2022 Petr Pucil <[email protected]> | |
* | |
* SPDX-License-Identifier: Apache-2.0 | |
*/ | |
"use strict"; | |
// Base `readBitsIntLe` implemenation: https://github.com/kaitai-io/kaitai_struct_javascript_runtime/blob/abf5542/KaitaiStream.js#L486-L525 | |
// Diff between `readBitsIntLe` and `readBitsIntLeV2` is as follows: | |
/* | |
--- 1/readBitsIntLe.js | |
+++ 2/readBitsIntLeV2.js | |
@@ -1,4 +1,4 @@ | |
-KaitaiStream.prototype.readBitsIntLe = function(n) { | |
+KaitaiStream.prototype.readBitsIntLeV2 = function(n) { | |
// JS only supports bit operations on 32 bits | |
if (n > 32) { | |
throw new RangeError("readBitsIntLe: the maximum supported bit length is 32 (tried to read " + n + " bits)"); | |
@@ -11,9 +11,21 @@ KaitaiStream.prototype.readBitsIntLe = function(n) { | |
// 8 bits => 1 byte | |
// 9 bits => 2 bytes | |
var bytesNeeded = ((bitsNeeded - 1) >> 3) + 1; // `ceil(bitsNeeded / 8)` (NB: `x >> 3` is `floor(x / 8)`) | |
- var buf = this.readBytes(bytesNeeded); | |
- for (var i = 0; i < bytesNeeded; i++) { | |
- res |= buf[i] << (i * 8); | |
+ var shift = 0; | |
+ switch (bytesNeeded) { | |
+ case 4: | |
+ res = this.readU4le(); | |
+ break; | |
+ case 3: | |
+ res = this.readU1(); | |
+ shift = 8; | |
+ // fallthrough | |
+ case 2: | |
+ res |= this.readU2le() << shift; | |
+ break; | |
+ case 1: | |
+ res = this.readU1(); | |
+ break; | |
} | |
// NB: in JavaScript, bit shift operators always shift by modulo 32 of the right-hand operand (see | |
*/ | |
const KaitaiStream = require('./KaitaiStream'); | |
const b = require('benny'); | |
const randomData = Uint8Array.from(new Array(24), v => (Math.random() * 0x1_00) >>> 0); | |
const _io = new KaitaiStream(randomData); | |
const funcRef = KaitaiStream.prototype.readBitsIntLe.bind(_io); | |
const funcV2 = KaitaiStream.prototype.readBitsIntLeV2.bind(_io); | |
function benchIter(io, func) { | |
io.seek(0); | |
io.alignToByte(); | |
const rand = (Math.random() * 0x1_0000_0000) >>> 0; | |
const a = func(1 + (rand & 0b11111)); | |
const b = func(1 + ((rand & 0b11111_00000) >>> 5)); | |
const c = func(1 + ((rand & 0b11111_00000_00000) >>> 10)); | |
const d = func(1 + ((rand & 0b11111_00000_00000_00000) >>> 15)); | |
const e = func(1 + ((rand & 0b11111_00000_00000_00000_00000) >>> 20)); | |
const f = func(1 + ((rand & 0b11111_00000_00000_00000_00000_00000) >>> 25)); | |
} | |
function run() { | |
return b.suite( | |
'readBitsIntLe suite', | |
b.add('KaitaiStream#readBitsIntLe', benchIter.bind(null, _io, funcRef)), | |
b.add('KaitaiStream#readBitsIntLeV2', benchIter.bind(null, _io, funcV2)), | |
b.cycle(), | |
b.complete(), | |
); | |
} | |
run(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment