datasette/perf/request-response/patches/db-adjacent-1-cache-versions-probe.diff
Claude d1dbb40362
Add request/response profiling harness and proposed optimisation patches
Tools for profiling Datasette's request/response cycle in-process with
Python 3.15's profiling.sampling, plus the patches proposed by the study
(one per optimisation, and ALL-combined.diff). The patches are not
applied to the code. A report with measurements follows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F8mEgRS8swZfYqwqrVMeo5
2026-10-13 00:12:35 +00:00

43 lines
1.8 KiB
Diff

diff --git a/datasette/app.py b/datasette/app.py
index 001ce9b..a3522a8 100644
--- a/datasette/app.py
+++ b/datasette/app.py
@@ -8,6 +8,7 @@ if TYPE_CHECKING:
from datasette.permissions import Resource
from datasette.tokens import TokenRestrictions
import collections
+import copy
import dataclasses
import datetime
import functools
@@ -589,6 +590,7 @@ class Datasette:
self._settings = dict(DEFAULT_SETTINGS, **(config_settings), **(settings or {}))
self.renderers = {} # File extension -> (renderer, can_render) functions
self.version_note = version_note
+ self._versions_cache = None
if self.setting("num_sql_threads") == 0:
self.executor = None
else:
@@ -2380,6 +2382,22 @@ ORDER BY allowed.parent, allowed.child
return {"databases": await self._connected_databases_for_actor(request.actor)}
def _versions(self):
+ # Probing SQLite (opening a connection, running every
+ # prepare_connection hook, creating FTS virtual tables) is slow and
+ # the answer only changes if the configured extensions, the
+ # registered prepare_connection hooks or the version note change.
+ cache_key = (
+ tuple(self.sqlite_extensions),
+ tuple(pm.hook.prepare_connection.get_hookimpls()),
+ self.version_note,
+ )
+ cached = self._versions_cache
+ if cached is None or cached[0] != cache_key:
+ cached = (cache_key, self._versions_uncached())
+ self._versions_cache = cached
+ return copy.deepcopy(cached[1])
+
+ def _versions_uncached(self):
conn = sqlite3.connect(":memory:")
self._prepare_connection(conn, "_memory")
sqlite_version = conn.execute("select sqlite_version()").fetchone()[0]