Skip to content

Commit c6dd8c5

Browse files
committed
Memorize shell documentation lookup
Every onHover or completion result takes ~10 ms to look up on a new Macbook. Let us save those CPU cycles for something better.
1 parent 6e99eb0 commit c6dd8c5

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

server/src/util/__tests__/sh.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,3 +491,24 @@ BSD April 12, 2003 BSD`)
491491
).toMatchSnapshot()
492492
})
493493
})
494+
495+
describe('memorize', () => {
496+
it('memorizes a function', async () => {
497+
const fnRaw = jest.fn(async args => args)
498+
const arg1 = { one: '1' }
499+
const arg2 = { another: { word: 'word' } }
500+
const fnMemorized = sh.memorize(fnRaw)
501+
502+
const arg1CallResult1 = await fnMemorized(arg1)
503+
const arg1CallResult2 = await fnMemorized(arg1)
504+
505+
const arg2CallResult1 = await fnMemorized(arg2)
506+
const arg2CallResult2 = await fnMemorized(arg2)
507+
508+
expect(fnRaw).toHaveBeenCalledTimes(2)
509+
expect(fnRaw).toHaveBeenCalledWith(arg2)
510+
511+
expect(arg1CallResult1).toBe(arg1CallResult2)
512+
expect(arg2CallResult1).toBe(arg2CallResult2)
513+
})
514+
})

server/src/util/sh.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export function execShellScript(body: string): Promise<string> {
2727
/**
2828
* Get documentation for the given word by usingZZ help and man.
2929
*/
30-
export async function getShellDocumentation({
30+
export async function getShellDocumentationWithoutCache({
3131
word,
3232
}: {
3333
word: string
@@ -84,3 +84,27 @@ export function formatManOutput(manOutput: string): string {
8484

8585
return formattedManOutput
8686
}
87+
88+
/**
89+
* Only works for one-parameter (serializable) functions.
90+
*/
91+
export function memorize<T extends Function>(func: T): T {
92+
const cache = new Map()
93+
94+
const returnFunc = async function(arg: any) {
95+
const cacheKey = JSON.stringify(arg)
96+
97+
if (cache.has(cacheKey)) {
98+
return cache.get(cacheKey)
99+
}
100+
101+
const result = await func(arg)
102+
103+
cache.set(cacheKey, result)
104+
return result
105+
}
106+
107+
return returnFunc as any
108+
}
109+
110+
export const getShellDocumentation = memorize(getShellDocumentationWithoutCache)

0 commit comments

Comments
 (0)