Skip to content
This repository was archived by the owner on Aug 1, 2025. It is now read-only.

Commit b50e9c6

Browse files
Autocomplete: Split debounce into two chunks, race the second part with the context retrieving (#3149)
This PR splits the debounce time into two logical chunk. The first 25ms (regardless of how long the debounce time is defined), the behavior will be like it is now: We batch events and don't do any concurrent work. However after 25ms (which, remember, was the debounce time we had until recently), we start to fetch the context in parallel. The idea is that we have shave off up to 50ms from the context retrieval time. Here's a visualization of a trace: <img width="1724" alt="Screenshot 2024-02-13 at 11 37 12" src="https://github.com/sourcegraph/cody/assets/458591/d8366a19-d0dd-4d20-a2bc-3b301d5e6211"> As you can see in this specific example, context retrieval could almost be free. One caveat here is that this _will_ increase CPU pressure (since we start fetching context a bit earlier). That's why I think 25ms is a good value for this since we have used it in the past with the same retrieval algorithm quite successfully. ## Test plan - Ensure AC still works - Check out a trace <img width="1718" alt="Screenshot 2024-02-13 at 11 47 14" src="https://github.com/sourcegraph/cody/assets/458591/37acfa14-f4a2-421b-813c-c5dd2b25b174">
1 parent 1774aa6 commit b50e9c6

File tree

5 files changed

+40
-15
lines changed

5 files changed

+40
-15
lines changed

vscode/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ This is a log of all notable changes to Cody for VS Code. [Unreleased] changes a
1414

1515
- Autocomplete: Removes the latency for cached completions. [https://github.com/sourcegraph/cody/pull/3138](https://github.com/sourcegraph/cody/pull/3138)
1616
- Autocomplete: Enable the recent jaccard similarity improvements by default. [pull/3135](https://github.com/sourcegraph/cody/pull/3135)
17+
- Autocomplete: Start retrieval phase earlier to improve latency. [pull/3149](https://github.com/sourcegraph/cody/pull/3149)
1718

1819
## [1.4.3]
1920

vscode/src/completions/get-inline-completions-tests/helpers.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ import {
3232
} from '../providers/anthropic'
3333
import type { ProviderOptions } from '../providers/provider'
3434
import { RequestManager } from '../request-manager'
35-
import { documentAndPosition, sleep } from '../test-helpers'
35+
import { documentAndPosition } from '../test-helpers'
3636
import { pressEnterAndGetIndentString } from '../providers/hot-streak'
3737
import { completionProviderConfig } from '../completion-provider-config'
3838
import { emptyMockFeatureFlagProvider } from '../../testutils/mocks'
39+
import { sleep } from '../utils'
3940

4041
// The dedent package seems to replace `\t` with `\\t` so in order to insert a tab character, we
4142
// have to use interpolation. We abbreviate this to `T` because ${T} is exactly 4 characters,

vscode/src/completions/get-inline-completions.ts

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import type { InlineCompletionItemWithAnalytics } from './text-processing/proces
2828
import type { ProvideInlineCompletionsItemTraceData } from './tracer'
2929
import { isValidTestFile } from '../commands/utils/test-commands'
3030
import { completionProviderConfig } from './completion-provider-config'
31+
import { sleep } from './utils'
3132

3233
export interface InlineCompletionsParams {
3334
// Context
@@ -306,6 +307,21 @@ async function doGetInlineCompletions(
306307
}
307308
}
308309

310+
const debounceTime =
311+
triggerKind !== TriggerKind.Automatic
312+
? 0
313+
: ((multiline ? debounceInterval?.multiLine : debounceInterval?.singleLine) ?? 0) +
314+
(artificialDelay ?? 0)
315+
316+
// We split the desired debounceTime into two chunks. One that is at most 25ms where every
317+
// further execution is halted...
318+
const waitInterval = Math.min(debounceTime, 25)
319+
// ...and one for the remaining time where we can already start retrieving context in parallel.
320+
const remainingInterval = debounceTime - waitInterval
321+
if (waitInterval > 0) {
322+
await wrapInActiveSpan('autocomplete.debounce.wait', () => sleep(waitInterval))
323+
}
324+
309325
// Debounce to avoid firing off too many network requests as the user is still typing.
310326
await wrapInActiveSpan('autocomplete.debounce', async () => {
311327
const interval =
@@ -324,19 +340,26 @@ async function doGetInlineCompletions(
324340
setIsLoading?.(true)
325341
CompletionLogger.start(logId)
326342

327-
// Fetch context
328-
const contextResult = await wrapInActiveSpan('autocomplete.retrieve', async () => {
329-
return contextMixer.getContext({
330-
document,
331-
position,
332-
docContext,
333-
abortSignal,
334-
maxChars: providerConfig.contextSizeHints.totalChars,
335-
})
336-
})
343+
// Fetch context and apply remaining debounce time
344+
const [contextResult] = await Promise.all([
345+
wrapInActiveSpan('autocomplete.retrieve', () =>
346+
contextMixer.getContext({
347+
document,
348+
position,
349+
docContext,
350+
abortSignal,
351+
maxChars: providerConfig.contextSizeHints.totalChars,
352+
})
353+
),
354+
remainingInterval > 0
355+
? wrapInActiveSpan('autocomplete.debounce.remaining', () => sleep(remainingInterval))
356+
: null,
357+
])
358+
337359
if (abortSignal?.aborted) {
338360
return null
339361
}
362+
340363
tracer?.({ context: contextResult })
341364

342365
const completionProvider = getCompletionProvider({

vscode/src/completions/test-helpers.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,3 @@ export function documentAndPosition(
6060
export function nextTick(): Promise<void> {
6161
return new Promise(resolve => setTimeout(resolve, 0))
6262
}
63-
64-
export function sleep(ms: number): Promise<void> {
65-
return new Promise(resolve => setTimeout(resolve, ms))
66-
}

vscode/src/completions/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,7 @@ function createTimeout(timeoutMs: number): Promise<never> {
131131
setTimeout(() => reject(new TimeoutError('The request timed out')), timeoutMs)
132132
)
133133
}
134+
135+
export function sleep(ms: number): Promise<void> {
136+
return new Promise(resolve => setTimeout(resolve, ms))
137+
}

0 commit comments

Comments
 (0)