Perf: repalce String#localeCompare w/ simple ASCII-only compare

This commit is contained in:
SukkaW 2024-11-21 21:51:05 +08:00
parent 200da7a2be
commit c6f3a67711
5 changed files with 28 additions and 6 deletions

View File

@ -7,7 +7,7 @@ import { treeDir } from './lib/tree-dir';
import type { TreeType, TreeTypeArray } from './lib/tree-dir';
import { OUTPUT_MOCK_DIR, OUTPUT_MODULES_DIR, PUBLIC_DIR, ROOT_DIR } from './constants/dir';
import { mkdirp, writeFile } from './lib/misc';
import { fastStringCompare, mkdirp, writeFile } from './lib/misc';
import picocolors from 'picocolors';
import { compareAndWriteFile } from './lib/create-file';
@ -90,7 +90,7 @@ const priorityOrder: Record<'default' | string & {}, number> = {
LICENSE: 70,
default: Number.MAX_VALUE
};
const prioritySorter = (a: TreeType, b: TreeType) => ((priorityOrder[a.name] || priorityOrder.default) - (priorityOrder[b.name] || priorityOrder.default)) || a.name.localeCompare(b.name);
const prioritySorter = (a: TreeType, b: TreeType) => ((priorityOrder[a.name] || priorityOrder.default) - (priorityOrder[b.name] || priorityOrder.default)) || fastStringCompare(a.name, b.name);
const html = (string: TemplateStringsArray, ...values: any[]) => string.reduce((acc, str, i) => acc + str + (values[i] ?? ''), '');

View File

@ -21,6 +21,26 @@ export function fastStringArrayJoin(arr: string[], sep: string) {
return result;
}
export function fastStringCompare(a: string, b: string) {
const lenA = a.length;
const lenB = b.length;
const minLen = lenA < lenB ? lenA : lenB;
for (let i = 0; i < minLen; ++i) {
const ca = a.charCodeAt(i);
const cb = b.charCodeAt(i);
if (ca > cb) return 1;
if (ca < cb) return -1;
}
if (lenA === lenB) {
return 0;
}
return lenA > lenB ? 1 : -1;
};
interface Write {
(
destination: string,

View File

@ -5,6 +5,7 @@ import type { SingboxSourceFormat } from '../singbox';
import * as tldts from 'tldts-experimental';
import { looseTldtsOpt } from '../../constants/loose-tldts-opt';
import { fastStringCompare } from '../misc';
type Preprocessed = string[];
@ -89,7 +90,7 @@ export class DomainsetOutput extends RuleOutput<Preprocessed> {
)
.entries())
.filter(a => a[1] > 9)
.sort((a, b) => (b[1] - a[1]) || a[0].localeCompare(b[0]))
.sort((a, b) => (b[1] - a[1]) || fastStringCompare(a[0], b[0]))
.map(([domain, count]) => `${domain}${' '.repeat(100 - domain.length)}${count}`);
}

View File

@ -3,10 +3,11 @@
// enough when sorting.
import * as tldts from 'tldts-experimental';
import { looseTldtsOpt } from '../constants/loose-tldts-opt';
import { fastStringCompare } from './misc';
export function compare(a: string, b: string) {
if (a === b) return 0;
return (a.length - b.length) || a.localeCompare(b);
return (a.length - b.length) || fastStringCompare(a, b);
}
export function buildParseDomainMap(inputs: string[]) {

View File

@ -2,7 +2,7 @@
* Hostbane-Optimized Trie based on Mnemonist Trie
*/
import { fastStringArrayJoin } from './misc';
import { fastStringArrayJoin, fastStringCompare } from './misc';
import util from 'node:util';
import { noop } from 'foxact/noop';
import FIFO from './fifo';
@ -251,7 +251,7 @@ abstract class Triebase<Meta = any> {
static compare(this: void, a: string, b: string) {
if (a === b) return 0;
return (a.length - b.length) || a.localeCompare(b);
return (a.length - b.length) || fastStringCompare(a, b);
}
private walkWithSort(