mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
perf(coderd): build the workspace build fan-out maps once per batch (#28074)
`convertWorkspaceBuild` rebuilt seven maps from the caller's global slices on every call and rescanned the provisioner daemon rows to filter by job ID. `convertWorkspaceBuilds` calls it once per build with identical slices, so map construction cost `O(builds x rows)` where `O(rows)` suffices — quadratic in the number of workspaces on `GET /api/v2/workspaces`. The maps move into a `workspaceBuildIndex` built once per batch, keyed exactly as before and now including daemons by job ID. `convertWorkspaceBuild` takes the index instead of eight slices. Its parent already hoisted `workspaceByID`, `jobByID`, and `templateVersionByID` out of the same loop; this makes the rest consistent. Agents are sorted while the index is built, so a resource read by several builds is sorted once rather than once per build. Same comparator over the same rows, so the order is unchanged; `TestConvertWorkspaceBuildsAgentOrder` covers it. `BenchmarkConvertWorkspaceBuilds`, 5 resources x 2 agents x 4 apps per build: | builds | ns/op | B/op | allocs/op | | --- | --- | --- | --- | | 1 | 48.3k -> 48.1k | 121k -> 125k | 342 -> 359 | | 25 | 12.7M -> 1.34M | 38.0MB -> 3.2MB | 69,621 -> 8,347 | | 100 | 186M -> 5.67M | 596MB -> 13.0MB | 1,024,941 -> 33,080 | Single-build conversion is a wash (one extra struct allocation); the quadratic term is gone. Addresses the map-allocation half of PLAT-386 / #27205. Bounding the page size is separate (#28040) and does not remove this cost: at 100 workspaces per page it is still 100 passes over every resource, agent, app, script, log source, status, and daemon row in the page. --- Created with Coder Agents on behalf of @jscottmiller.
This commit is contained in:
@@ -834,15 +834,8 @@ func createWorkspace(
|
||||
ProvisionerJob: *provisionerJob,
|
||||
QueuePosition: 0,
|
||||
},
|
||||
[]database.WorkspaceResource{},
|
||||
[]database.WorkspaceResourceMetadatum{},
|
||||
[]database.WorkspaceAgent{},
|
||||
[]database.WorkspaceApp{},
|
||||
[]database.WorkspaceAppStatus{},
|
||||
[]database.GetWorkspaceAgentScriptsByAgentIDsRow{},
|
||||
[]database.WorkspaceAgentLogSource{},
|
||||
newWorkspaceBuildIndex(nil, nil, nil, nil, nil, nil, nil, provisionerDaemons),
|
||||
database.TemplateVersion{},
|
||||
provisionerDaemons,
|
||||
)
|
||||
if err != nil {
|
||||
return codersdk.Workspace{}, httperror.NewResponseError(http.StatusInternalServerError, codersdk.Response{
|
||||
|
||||
Reference in New Issue
Block a user