Files
lintunes/lintunes/perf.py
T
travandClaude Fable 5 332b47a018 v0.1.1: perf timings + single-save tag writes + coalesced browser rebuild
Diagnosing the Ctrl+I save hang on the Debian machine (GUI thread blocks
past mutter's 5s check-alive):

- lintunes/perf.py: timed() context manager logging wall-clock ms at INFO
  on lintunes.perf — instruments tag/artwork saves, file moves,
  edit_track(s)_fields, the browser rebuild, smart recompute, and the
  debounced JSON flush, so the slow machine can tell us which stage
  eats the time (journalctl --user or a terminal run).
- tagging.write_tags: ONE parse + ONE save per edit. grouping/
  compilation/bpm ride the main save via registered Easy keys
  (GRP1/TCMP/TBPM on EasyID3, cpil on EasyMP4) instead of
  _write_extra_tags re-parsing and re-saving the audio file.
- LibraryView: browser rebuilds coalesce through a 0ms single-shot
  timer — an N-track Get Info edit rebuilds the genre/artist/album
  cascade once instead of N times over the whole library.

Moving the writes off the GUI thread is deliberately deferred until the
Debian timings say which stage dominates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 18:25:56 -04:00

23 lines
686 B
Python

"""Wall-clock timing for the save/edit hot paths.
Logs at INFO on the ``lintunes.perf`` logger, so a normal desktop launch
records where the time went (visible via ``journalctl --user`` or a
terminal run). Used to diagnose GUI-thread stalls on slow machines.
"""
import logging
import time
from contextlib import contextmanager
log = logging.getLogger("lintunes.perf")
@contextmanager
def timed(label: str, *args):
"""``with timed("write_tags %s", path):`` — logs the block's duration."""
start = time.perf_counter()
try:
yield
finally:
ms = (time.perf_counter() - start) * 1000
log.info("%s: %.0f ms", label % args if args else label, ms)