19 lines
2.0 KiB
Markdown
19 lines
2.0 KiB
Markdown
# Performance notes
|
|
|
|
## The `?seo=` article filter
|
|
|
|
`GET /v1/article/` assesses the SEO status of articles in memory, because the status depends on the body, the site template and the authors. Every request assesses every visible article once, to fill `counts.suggestions`, and `?seo=` reuses that assessment to filter before paging. The cost therefore grows with the number of articles, not with the page size.
|
|
|
|
`TestSeoFilterPerformance` in `test/seo_filter_performance_test.go` (skipped with `-short`) measures 5,000 articles of about 5 KB each in one site on a temporary SQLite file, every article with suggestions, slowest of 3 runs:
|
|
|
|
| Request | Time |
|
|
| --- | --- |
|
|
| `?seo=suggestions&size=25` | 315 to 338 ms |
|
|
| default page, no `?seo=` | 307 to 329 ms |
|
|
|
|
The target is 300 ms for 5,000 articles. Both requests sit slightly above it on the development machine, so the test logs the target but only fails above 500 ms; no cache or index was added. Re-run it with `go test -tags nofrontend ./test/... -run TestSeoFilterPerformance -v -count=1` after a change to the assessment rules or the article repository.
|
|
|
|
## The `?seo=` filter of the grouped list
|
|
|
|
`GET /v1/article/?group=story` uses the same assessment. The versions whose status matches (and, with `q`, whose title matches: the title search runs once per request through `article.Repository.FindTitleMatches`) are handed to the repository as `StoryFilters.VersionIDs`. That set can be larger than any bind-parameter limit (SQLite accepts 32,766 parameters), so it never becomes an `IN (?, …)` list: the repository reads the qualifying `(story_id, id)` pairs and the ordered story rows with id-only projections and keeps the members of the set in memory before paging. `ListByStories` reads the versions of the page without their bodies and only those the caller may read; the representative's body comes from the assessment pass, which still reads every visible body because the status depends on it. `TestArticleStoryListSEOFilterAtScaleSQLite` covers 40,001 versions.
|