Perf: faster string[] join

This commit is contained in:
SukkaW 2024-06-28 17:25:54 +08:00
parent 724dcdf1ad
commit 1d8c991baf
4 changed files with 27 additions and 6 deletions

View File

@ -4,6 +4,7 @@ import os from 'os';
import path from 'path'; import path from 'path';
import { mkdirSync } from 'fs'; import { mkdirSync } from 'fs';
import picocolors from 'picocolors'; import picocolors from 'picocolors';
import { fastStringArrayJoin } from './misc';
const identity = (x: any) => x; const identity = (x: any) => x;
@ -215,7 +216,7 @@ const separator = '\u0000';
// const textDecoder = new TextDecoder(); // const textDecoder = new TextDecoder();
// export const serializeString = (str: string) => textEncoder.encode(str); // export const serializeString = (str: string) => textEncoder.encode(str);
// export const deserializeString = (str: string) => textDecoder.decode(new Uint8Array(str.split(separator).map(Number))); // export const deserializeString = (str: string) => textDecoder.decode(new Uint8Array(str.split(separator).map(Number)));
export const serializeSet = (set: Set<string>) => Array.from(set).join(separator); export const serializeSet = (set: Set<string>) => fastStringArrayJoin(Array.from(set), separator);
export const deserializeSet = (str: string) => new Set(str.split(separator)); export const deserializeSet = (str: string) => new Set(str.split(separator));
export const serializeArray = (arr: string[]) => arr.join(separator); export const serializeArray = (arr: string[]) => fastStringArrayJoin(arr, separator);
export const deserializeArray = (str: string) => str.split(separator); export const deserializeArray = (str: string) => str.split(separator);

View File

@ -5,6 +5,7 @@ import picocolors from 'picocolors';
import type { Span } from '../trace'; import type { Span } from '../trace';
import path from 'path'; import path from 'path';
import { sort } from './timsort'; import { sort } from './timsort';
import { fastStringArrayJoin } from './misc';
export async function compareAndWriteFile(span: Span, linesA: string[], filePath: string) { export async function compareAndWriteFile(span: Span, linesA: string[], filePath: string) {
let isEqual = true; let isEqual = true;
@ -69,7 +70,7 @@ export async function compareAndWriteFile(span: Span, linesA: string[], filePath
await span.traceChildAsync(`writing ${filePath}`, async () => { await span.traceChildAsync(`writing ${filePath}`, async () => {
// if (linesALen < 10000) { // if (linesALen < 10000) {
return Bun.write(file, `${linesA.join('\n')}\n`); return Bun.write(file, fastStringArrayJoin(linesA, '\n') + '\n');
// } // }
// const writer = file.writer(); // const writer = file.writer();

View File

@ -1 +1,18 @@
export const isTruthy = <T>(i: T | 0 | '' | false | null | undefined): i is T => !!i; export const isTruthy = <T>(i: T | 0 | '' | false | null | undefined): i is T => !!i;
export const fastStringArrayJoin = (arr: string[], sep: string) => {
let result = '';
for (let i = 0, len = arr.length; i < len; i++) {
if (i !== 0) {
result += sep;
}
result += arr[i];
}
return result;
};
export const fastStringArrayJoin2 = (arr: string[], sep: string) => {
return arr.reduce((acc, cur, index) => {
return index === 0 ? cur : acc + sep + cur;
}, '');
};

View File

@ -2,6 +2,8 @@
* Suffix Trie based on Mnemonist Trie * Suffix Trie based on Mnemonist Trie
*/ */
import { fastStringArrayJoin } from './misc';
// const { Error, Bun, JSON, Symbol } = globalThis; // const { Error, Bun, JSON, Symbol } = globalThis;
const noop = () => { /** noop */ }; const noop = () => { /** noop */ };
@ -262,7 +264,7 @@ export const createTrie = (from?: string[] | Set<string> | null, hostnameMode =
inputTokens inputTokens
); );
return hostnameMode ? matches.map((m) => (m as string[]).join('')) : matches as string[]; return hostnameMode ? matches.map((m) => fastStringArrayJoin(m as string[], '')) : matches as string[];
}; };
/** /**
@ -279,7 +281,7 @@ export const createTrie = (from?: string[] | Set<string> | null, hostnameMode =
if (res === null) return; if (res === null) return;
const onMatches = hostnameMode const onMatches = hostnameMode
? (suffix: string[]) => set.delete(suffix.join('')) ? (suffix: string[]) => set.delete(fastStringArrayJoin(suffix, ''))
: (suffix: string) => set.delete(suffix); : (suffix: string) => set.delete(suffix);
walk( walk(
@ -327,7 +329,7 @@ export const createTrie = (from?: string[] | Set<string> | null, hostnameMode =
walk(suffix => { walk(suffix => {
results.push( results.push(
isHostnameMode(suffix) ? suffix.join('') : suffix isHostnameMode(suffix) ? fastStringArrayJoin(suffix, '') : suffix
); );
}); });