mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Refactor `duration` to store time in seconds
This commit is contained in:
@@ -1,20 +1,22 @@
|
||||
"""Measure durations of Sphinx processing."""
|
||||
"""Measure document reading durations."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
import time
|
||||
from itertools import islice
|
||||
from operator import itemgetter
|
||||
from typing import Any, cast
|
||||
|
||||
from docutils import nodes
|
||||
from typing import TYPE_CHECKING, cast
|
||||
|
||||
import sphinx
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.domains import Domain
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -23,10 +25,10 @@ class DurationDomain(Domain):
|
||||
name = 'duration'
|
||||
|
||||
@property
|
||||
def reading_durations(self) -> dict[str, timedelta]:
|
||||
def reading_durations(self) -> dict[str, float]:
|
||||
return self.data.setdefault('reading_durations', {})
|
||||
|
||||
def note_reading_duration(self, duration: timedelta) -> None:
|
||||
def note_reading_duration(self, duration: float) -> None:
|
||||
self.reading_durations[self.env.docname] = duration
|
||||
|
||||
def clear(self) -> None:
|
||||
@@ -35,7 +37,7 @@ class DurationDomain(Domain):
|
||||
def clear_doc(self, docname: str) -> None:
|
||||
self.reading_durations.pop(docname, None)
|
||||
|
||||
def merge_domaindata(self, docnames: list[str], otherdata: dict[str, timedelta]) -> None:
|
||||
def merge_domaindata(self, docnames: list[str], otherdata: dict[str, float]) -> None:
|
||||
for docname, duration in otherdata.items():
|
||||
if docname in docnames:
|
||||
self.reading_durations[docname] = duration
|
||||
@@ -44,7 +46,7 @@ class DurationDomain(Domain):
|
||||
def on_builder_inited(app: Sphinx) -> None:
|
||||
"""Initialize DurationDomain on bootstrap.
|
||||
|
||||
This clears results of last build.
|
||||
This clears the results of the last build.
|
||||
"""
|
||||
domain = cast(DurationDomain, app.env.get_domain('duration'))
|
||||
domain.clear()
|
||||
@@ -52,31 +54,31 @@ def on_builder_inited(app: Sphinx) -> None:
|
||||
|
||||
def on_source_read(app: Sphinx, docname: str, content: list[str]) -> None:
|
||||
"""Start to measure reading duration."""
|
||||
app.env.temp_data['started_at'] = datetime.now()
|
||||
app.env.temp_data['started_at'] = time.monotonic()
|
||||
|
||||
|
||||
def on_doctree_read(app: Sphinx, doctree: nodes.document) -> None:
|
||||
"""Record a reading duration."""
|
||||
started_at = app.env.temp_data['started_at']
|
||||
duration = datetime.now() - started_at
|
||||
duration = time.monotonic() - started_at
|
||||
domain = cast(DurationDomain, app.env.get_domain('duration'))
|
||||
domain.note_reading_duration(duration)
|
||||
|
||||
|
||||
def on_build_finished(app: Sphinx, error: Exception) -> None:
|
||||
"""Display duration ranking on current build."""
|
||||
"""Display duration ranking on the current build."""
|
||||
domain = cast(DurationDomain, app.env.get_domain('duration'))
|
||||
durations = sorted(domain.reading_durations.items(), key=itemgetter(1), reverse=True)
|
||||
if not durations:
|
||||
if not domain.reading_durations:
|
||||
return
|
||||
durations = sorted(domain.reading_durations.items(), key=itemgetter(1), reverse=True)
|
||||
|
||||
logger.info('')
|
||||
logger.info(__('====================== slowest reading durations ======================='))
|
||||
for docname, d in islice(durations, 5):
|
||||
logger.info('%d.%03d %s', d.seconds, d.microseconds / 1000, docname)
|
||||
logger.info(f'{d:.3f} {docname}') # NoQA: G004
|
||||
|
||||
|
||||
def setup(app: Sphinx) -> dict[str, Any]:
|
||||
def setup(app: Sphinx) -> dict[str, bool | str]:
|
||||
app.add_domain(DurationDomain)
|
||||
app.connect('builder-inited', on_builder_inited)
|
||||
app.connect('source-read', on_source_read)
|
||||
|
||||
Reference in New Issue
Block a user