Optimize packed WASM base64 decoding loop (#404)

This commit is contained in:
Jaco
2022-07-19 08:45:11 +02:00
committed by GitHub
parent b36cd04348
commit fe91118385
2 changed files with 19 additions and 5 deletions

View File

@@ -1,5 +1,12 @@
# CHANGELOG
## master
Changes:
- Optimize packed WASM base64 decoding loop
## 6.2.3 Jul 7, 2022
Changes:

View File

@@ -1,11 +1,16 @@
// Copyright 2019-2022 @polkadot/wasm-util authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Use an array for our indexer - this is faster than using map access. In
// this case we assume ASCII-only inputs, so we cannot overflow the array
const chr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
const map: Record<string, number> = {};
const map = new Array<number>(256);
// We use charCodeAt for access here and in the decoder loop - this is faster
// on lookups (array + numbers) and also faster than accessing the specific
// character via data[i]
for (let i = 0; i < chr.length; i++) {
map[chr[i]] = i;
map[chr.charCodeAt(i)] = i;
}
/**
@@ -16,16 +21,18 @@ for (let i = 0; i < chr.length; i++) {
* slightly slower, but it is platform independent.
*
* For our usage, since we have access to the static final size (where used), we
* decode to a specified output buffer.
* decode to a specified output buffer. This also means we have applied a number
* of optimizations based on this - checking out output position instead of chars.
*/
export function base64Decode (data: string, out: Uint8Array): Uint8Array {
const len = out.length;
let byte = 0;
let bits = 0;
let pos = -1;
for (let i = 0; i < data.length && data[i] !== '='; i++) {
for (let i = 0; pos < len; i++) {
// each character represents 6 bits
byte = (byte << 6) | map[data[i]];
byte = (byte << 6) | map[data.charCodeAt(i)];
// each byte needs to contain 8 bits
if ((bits += 6) >= 8) {