Skip to content

Commit 47bb23c

Browse files
usualomaEdamAme-x
andauthored
perf(trie-router): avoid calling spread operator for Object.create(null) (#3735)
* perf(trie-router): avoid calling spread operator for `Object.create(null)` This optimization is based on the discussion in the following Pull Request. Thanks to @EdamAme-x! #3732 Co-authored-by: EdamAmex <[email protected]> * perf(trie-router): make some #getHandlerSets parameters optional * fix(trie-router): fix #getHandlerSets bug --------- Co-authored-by: EdamAmex <[email protected]>
1 parent 979510f commit 47bb23c

1 file changed

Lines changed: 18 additions & 25 deletions

File tree

src/router/trie-router/node.ts

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ type HandlerParamsSet<T> = HandlerSet<T> & {
1313
params: Record<string, string>
1414
}
1515

16+
const emptyParams = Object.create(null)
17+
1618
export class Node<T> {
1719
#methods: Record<string, HandlerSet<T>>[]
1820

1921
#children: Record<string, Node<T>>
2022
#patterns: Pattern[]
2123
#order: number = 0
22-
#params: Record<string, string> = Object.create(null)
24+
#params: Record<string, string> = emptyParams
2325

2426
constructor(method?: string, handler?: T, children?: Record<string, Node<T>>) {
2527
this.#children = children || Object.create(null)
@@ -82,7 +84,7 @@ export class Node<T> {
8284
node: Node<T>,
8385
method: string,
8486
nodeParams: Record<string, string>,
85-
params: Record<string, string>
87+
params?: Record<string, string>
8688
): HandlerParamsSet<T>[] {
8789
const handlerSets: HandlerParamsSet<T>[] = []
8890
for (let i = 0, len = node.#methods.length; i < len; i++) {
@@ -91,23 +93,24 @@ export class Node<T> {
9193
const processedSet: Record<number, boolean> = {}
9294
if (handlerSet !== undefined) {
9395
handlerSet.params = Object.create(null)
94-
for (let i = 0, len = handlerSet.possibleKeys.length; i < len; i++) {
95-
const key = handlerSet.possibleKeys[i]
96-
const processed = processedSet[handlerSet.score]
97-
handlerSet.params[key] =
98-
params[key] && !processed ? params[key] : nodeParams[key] ?? params[key]
99-
processedSet[handlerSet.score] = true
100-
}
101-
10296
handlerSets.push(handlerSet)
97+
if (nodeParams !== emptyParams || (params && params !== emptyParams)) {
98+
for (let i = 0, len = handlerSet.possibleKeys.length; i < len; i++) {
99+
const key = handlerSet.possibleKeys[i]
100+
const processed = processedSet[handlerSet.score]
101+
handlerSet.params[key] =
102+
params?.[key] && !processed ? params[key] : nodeParams[key] ?? params?.[key]
103+
processedSet[handlerSet.score] = true
104+
}
105+
}
103106
}
104107
}
105108
return handlerSets
106109
}
107110

108111
search(method: string, path: string): [[T, Params][]] {
109112
const handlerSets: HandlerParamsSet<T>[] = []
110-
this.#params = Object.create(null)
113+
this.#params = emptyParams
111114

112115
// eslint-disable-next-line @typescript-eslint/no-this-alias
113116
const curNode: Node<T> = this
@@ -129,35 +132,25 @@ export class Node<T> {
129132
// '/hello/*' => match '/hello'
130133
if (nextNode.#children['*']) {
131134
handlerSets.push(
132-
...this.#getHandlerSets(
133-
nextNode.#children['*'],
134-
method,
135-
node.#params,
136-
Object.create(null)
137-
)
135+
...this.#getHandlerSets(nextNode.#children['*'], method, node.#params)
138136
)
139137
}
140-
handlerSets.push(
141-
...this.#getHandlerSets(nextNode, method, node.#params, Object.create(null))
142-
)
138+
handlerSets.push(...this.#getHandlerSets(nextNode, method, node.#params))
143139
} else {
144140
tempNodes.push(nextNode)
145141
}
146142
}
147143

148144
for (let k = 0, len3 = node.#patterns.length; k < len3; k++) {
149145
const pattern = node.#patterns[k]
150-
151-
const params = { ...node.#params }
146+
const params = node.#params === emptyParams ? {} : { ...node.#params }
152147

153148
// Wildcard
154149
// '/hello/*/foo' => match /hello/bar/foo
155150
if (pattern === '*') {
156151
const astNode = node.#children['*']
157152
if (astNode) {
158-
handlerSets.push(
159-
...this.#getHandlerSets(astNode, method, node.#params, Object.create(null))
160-
)
153+
handlerSets.push(...this.#getHandlerSets(astNode, method, node.#params))
161154
tempNodes.push(astNode)
162155
}
163156
continue

0 commit comments

Comments
 (0)