Skip to content

Commit b28b5d0

Browse files
committed
perf: use array-indexed lookup for execute handlers in hot path
Add a parallel array container for execute handlers (codes < 0x18) alongside the existing object. Setters populate both, the EXE fast-path reads from the array with nullish coalescing to avoid branching. ExecuteHandlerType updated to accept optional ident param to allow the ?? pattern with the fallback handler.
1 parent 32553b4 commit b28b5d0

2 files changed

Lines changed: 11 additions & 5 deletions

File tree

src/common/parser/EscapeSequenceParser.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
247247
// handler lookup containers
248248
protected _printHandler: PrintHandlerType;
249249
protected _executeHandlers: { [flag: number]: ExecuteHandlerType };
250+
protected _executeHandlersArr: (ExecuteHandlerType | undefined)[];
250251
protected _csiHandlers: IHandlerCollection<CsiHandlerType>;
251252
protected _escHandlers: IHandlerCollection<EscHandlerType>;
252253
protected readonly _oscParser: IOscParser;
@@ -290,11 +291,13 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
290291
this._errorHandlerFb = (state: IParsingState): IParsingState => state;
291292
this._printHandler = this._printHandlerFb;
292293
this._executeHandlers = Object.create(null);
294+
this._executeHandlersArr = new Array<ExecuteHandlerType | undefined>(0x18).fill(undefined);
293295
this._csiHandlers = Object.create(null);
294296
this._escHandlers = Object.create(null);
295297
this._register(toDisposable(() => {
296298
this._csiHandlers = Object.create(null);
297299
this._executeHandlers = Object.create(null);
300+
this._executeHandlersArr = new Array<ExecuteHandlerType | undefined>(0x18).fill(undefined);
298301
this._escHandlers = Object.create(null);
299302
}));
300303
this._oscParser = this._register(new OscParser());
@@ -381,10 +384,14 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
381384
}
382385

383386
public setExecuteHandler(flag: string, handler: ExecuteHandlerType): void {
384-
this._executeHandlers[flag.charCodeAt(0)] = handler;
387+
const code = flag.charCodeAt(0);
388+
this._executeHandlers[code] = handler;
389+
if (code < 0x18) this._executeHandlersArr[code] = handler;
385390
}
386391
public clearExecuteHandler(flag: string): void {
387-
if (this._executeHandlers[flag.charCodeAt(0)]) delete this._executeHandlers[flag.charCodeAt(0)];
392+
const code = flag.charCodeAt(0);
393+
if (this._executeHandlers[code]) delete this._executeHandlers[code];
394+
if (code < 0x18) this._executeHandlersArr[code] = undefined;
388395
}
389396
public setExecuteHandlerFallback(handler: ExecuteFallbackHandlerType): void {
390397
this._executeHandlerFb = handler;
@@ -655,8 +662,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
655662

656663
// EXE fast-path: common control bytes (0x00-0x17) in non-payload states
657664
if (code < 0x18 && this.currentState <= ParserState.CSI_IGNORE) {
658-
if (this._executeHandlers[code]) this._executeHandlers[code]();
659-
else this._executeHandlerFb(code);
665+
(this._executeHandlersArr[code] ?? this._executeHandlerFb)(code);
660666
this.precedingJoinState = 0;
661667
continue;
662668
}

src/common/parser/Types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export type EscFallbackHandlerType = (identifier: number) => void;
107107
/**
108108
* EXECUTE handler types.
109109
*/
110-
export type ExecuteHandlerType = () => boolean;
110+
export type ExecuteHandlerType = (ident?: number) => boolean;
111111
export type ExecuteFallbackHandlerType = (ident: number) => void;
112112

113113
/**

0 commit comments

Comments
 (0)