mirror of
https://github.com/simonw/datasette.git
synced 2026-11-06 02:08:31 +01:00
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
43 lines
1.8 KiB
Diff
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]
|