From e7ac095aced6a80dbf704ac2ea8c1b9bd112fbb3 Mon Sep 17 00:00:00 2001 From: Jaco Date: Mon, 20 Jun 2022 10:49:41 +0200 Subject: [PATCH] Slight improvment to hexToU8a (#1552) --- packages/util/src/hex/toU8a.spec.ts | 2 +- packages/util/src/hex/toU8a.ts | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/util/src/hex/toU8a.spec.ts b/packages/util/src/hex/toU8a.spec.ts index 04ac8a5b3..27901e157 100644 --- a/packages/util/src/hex/toU8a.spec.ts +++ b/packages/util/src/hex/toU8a.spec.ts @@ -54,7 +54,7 @@ describe('hexToU8a', (): void => { ).toThrow(/hex value to convert/); }); - perfCmp('hexToU8a', ['hexToU8aBuffer', 'hexToU8a'], 20, [[ptest]], (s: string, isSecond) => + perfCmp('hexToU8a', ['hexToU8aBuffer', 'hexToU8a'], 25, [[ptest]], (s: string, isSecond) => isSecond ? hexToU8a(s) : hexToU8aBuffer(s) diff --git a/packages/util/src/hex/toU8a.ts b/packages/util/src/hex/toU8a.ts index 69c67393d..a60a390df 100644 --- a/packages/util/src/hex/toU8a.ts +++ b/packages/util/src/hex/toU8a.ts @@ -3,7 +3,7 @@ import type { HexString } from '../types'; -import { hexStripPrefix } from './stripPrefix'; +import { REGEX_HEX_NOPREFIX, REGEX_HEX_PREFIXED } from '../is/hex'; const CHARS = '0123456789abcdef'; const UNHEX = new Array(256); @@ -36,8 +36,18 @@ export function hexToU8a (value?: HexString | string | null, bitLength = -1): Ui return new Uint8Array(); } - const str = hexStripPrefix(value); - const strLength = str.length / 2; + let s = 0; + + // we don't use hexStringPrefix here - that has substring which adds + // additional overhead. Instead we duplicate the logic, just incrementing + // the sactual string pointer, ignoring the prefix as required + if (REGEX_HEX_PREFIXED.test(value)) { + s = 2; + } else if (!REGEX_HEX_NOPREFIX.test(value)) { + throw new Error(`Expected hex value to convert, found '${value}'`); + } + + const strLength = (value.length - s) / 2; const endLength = Math.ceil( bitLength === -1 ? strLength @@ -48,12 +58,12 @@ export function hexToU8a (value?: HexString | string | null, bitLength = -1): Ui ? endLength - strLength : 0; - for (let i = offset, s = 0; i < endLength; i++, s += 2) { + for (let i = offset; i < endLength; i++, s += 2) { // The big factor here is actually the string lookups. If we do // HEX_TO_U16[value.substring()] we get an 10x slowdown. In the // same vein using charCodeAt (as opposed to value[s] or value.charAt(s)) is // also the faster operation by at least 2x with the character map above - result[i] = ((UNHEX[str.charCodeAt(s)] << 4) + UNHEX[str.charCodeAt(s + 1)]) | 0; + result[i] = (UNHEX[value.charCodeAt(s)] << 4) + UNHEX[value.charCodeAt(s + 1)]; } return result;