perf: use cache in NapProto

This commit is contained in:
pk5ls20 2024-11-04 14:42:16 +08:00
parent c4e1a3ab04
commit 81dbb9d980
No known key found for this signature in database
GPG Key ID: 6370ED7A169F493A

View File

@ -91,15 +91,12 @@ export type NapProtoEncodeStructType<T> = NapProtoStructType<T, true>;
export type NapProtoDecodeStructType<T> = NapProtoStructType<T, false>; export type NapProtoDecodeStructType<T> = NapProtoStructType<T, false>;
const NapProtoMsgCache = new Map<ProtoMessageType, MessageType<NapProtoStructType<ProtoMessageType, boolean>>>(); class NapProtoRealMsg<T extends ProtoMessageType> {
export class NapProtoMsg<T extends ProtoMessageType> {
private readonly _msg: T;
private readonly _field: PartialFieldInfo[]; private readonly _field: PartialFieldInfo[];
private readonly _proto_msg: MessageType<NapProtoStructType<T, boolean>>; private readonly _proto_msg: MessageType<NapProtoStructType<T, boolean>>;
private static cache = new WeakMap<ProtoMessageType, NapProtoRealMsg<any>>();
constructor(fields: T) { private constructor(fields: T) {
this._msg = fields;
this._field = Object.keys(fields).map(key => { this._field = Object.keys(fields).map(key => {
const field = fields[key]; const field = fields[key];
if (field.kind === 'scalar') { if (field.kind === 'scalar') {
@ -122,13 +119,22 @@ export class NapProtoMsg<T extends ProtoMessageType> {
name: key, name: key,
kind: 'message', kind: 'message',
repeat: field.repeat ? RepeatType.PACKED : RepeatType.NO, repeat: field.repeat ? RepeatType.PACKED : RepeatType.NO,
T: () => new NapProtoMsg(field.type())._proto_msg, T: () => NapProtoRealMsg.getInstance(field.type())._proto_msg,
}; };
} }
}) as PartialFieldInfo[]; }) as PartialFieldInfo[];
this._proto_msg = new MessageType<NapProtoStructType<T, boolean>>('nya', this._field); this._proto_msg = new MessageType<NapProtoStructType<T, boolean>>('nya', this._field);
} }
static getInstance<T extends ProtoMessageType>(fields: T): NapProtoRealMsg<T> {
let instance = this.cache.get(fields);
if (!instance) {
instance = new NapProtoRealMsg(fields);
this.cache.set(fields, instance);
}
return instance;
}
encode(data: NapProtoEncodeStructType<T>): Uint8Array { encode(data: NapProtoEncodeStructType<T>): Uint8Array {
return this._proto_msg.toBinary(this._proto_msg.create(data as PartialMessage<NapProtoEncodeStructType<T>>)); return this._proto_msg.toBinary(this._proto_msg.create(data as PartialMessage<NapProtoEncodeStructType<T>>));
} }
@ -137,3 +143,19 @@ export class NapProtoMsg<T extends ProtoMessageType> {
return this._proto_msg.fromBinary(data) as NapProtoDecodeStructType<T>; return this._proto_msg.fromBinary(data) as NapProtoDecodeStructType<T>;
} }
} }
export class NapProtoMsg<T extends ProtoMessageType> {
private realMsg: NapProtoRealMsg<T>;
constructor(fields: T) {
this.realMsg = NapProtoRealMsg.getInstance(fields);
}
encode(data: NapProtoEncodeStructType<T>): Uint8Array {
return this.realMsg.encode(data);
}
decode(data: Uint8Array): NapProtoDecodeStructType<T> {
return this.realMsg.decode(data);
}
}