tractor/ai/prompt-io/claude/20260702T155626Z_65bf9df5_p...

4.1 KiB
Raw Blame History

Raw AI output — gh #470 import tractor latency trim

All generated code is committed on the wkt/boot_latency_470 branch; per diff-ref mode each files content is referenced via its diff instead of copied verbatim.

Profiling findings (verbatim analysis output)

Baseline: import tractor ~0.39-0.42s wall.

python -X importtime + cProfile traced the cost NOT primarily to third-party deps (the issues hypothesis) but to tractor/log.py:get_logger() calling get_caller_mod() -> inspect.stack() at module level in ~39 tractor modules:

  • inspect.stack() builds FrameInfo (incl. src-file and line-context resolution) for EVERY frame on the stack; during nested imports the stack is dozens of importlib frames deep.
  • each FrameInfo resolution calls inspect.getmodule() which scans all of sys.modules per frame (1.4M ismodule() calls in one profiled import).
  • aggregate: ~244ms of tractor-own module “self” time vs ~20ms for ALL the issue-listed third-party deps (pdbp ~10ms, bidict ~4.5ms, multiaddr ~3.5ms, wrapt/colorlog ~1ms each); trio itself is ~70-100ms and unavoidable.

Generated changes

git diff main..wkt/boot_latency_470 -- tractor/log.py

get_caller_mod() rewritten from inspect.stack() + inspect.getmodule() to sys._getframe(frames_up) + frame.f_globals['__name__'] -> sys.modules lookup (O(1) vs O(stack x sys.modules)). Unused inspect imports dropped; FrameType imported from types. Also colorlog lazy-imported inside get_console_log().

git diff main..wkt/boot_latency_470 -- tractor/discovery/_addr.py

bidict import moved under TYPE_CHECKING (annotation-only use; _address_types is a plain dict literal).

git diff main..wkt/boot_latency_470 -- tractor/discovery/_multiaddr.py

from __future__ import annotations added; multiaddr import moved under TYPE_CHECKING + function-local imports in mk_maddr()/parse_maddr().

git diff main..wkt/boot_latency_470 -- tractor/ipc/_tcp.py tractor/ipc/_uds.py

Multiaddr imports moved under TYPE_CHECKING (annotation-only in both transports).

git diff main..wkt/boot_latency_470 -- tractor/runtime/_state.py

platformdirs lazy-imported inside get_rt_dir() (NOTE: still imported eagerly via UDSAddress.def_bindspace class-var eval; see follow-ups).

git diff main..wkt/boot_latency_470 -- tractor/devx/_frame_stack.py

pdbp + wrapt lazy-imported inside hide_runtime_frames() / api_frame() respectively.

git diff main..wkt/boot_latency_470 -- tractor/devx/debug/_trace.py tractor/devx/debug/_tty_lock.py

asyncio moved to TYPE_CHECKING + call-site local imports (asyncio.current_task() sites); tractor.to_asyncio.run_trio_task_in_future imports moved into the infected-aio runtime branches.

git diff main..wkt/boot_latency_470 -- tractor/spawn/_entry.py

run_as_asyncio_guest import moved into the infect_asyncio=True branches of _mp_main() / _trio_main().

git diff main..wkt/boot_latency_470 -- tractor/__init__.py

PEP 562 module __getattr__ added so tractor.to_asyncio attr-access still works (required by tests/test_child_manages_service_nursery.py and any downstream user) while keeping asyncio off the eager import path.

Measured results (verbatim)

  • import tractor: 0.39-0.42s -> ~0.145s (~65% cut)
  • start_actor spawn+boot+reg+cancel: ~0.40-0.44s -> ~0.179s/actor (n=5 sequential, warm parent)
  • post-change eager-module check: only pdbp + platformdirs of the issues list remain eager.

Known follow-ups (not implemented, deadline-bound)

  • pdbp (~10ms): still eager via devx/debug/_repl.py class bases (class PdbREPL(pdbp.Pdb)) + _tty_lock.py module-level @pdbp.hideframe; needs _repl restructure + PEP 562 in devx.debug.__init__.
  • platformdirs (~1.5ms): eager via UDSAddress.def_bindspace: ClassVar = get_rt_dir() class-body call; needs Address-protocol rework of def_bindspace to a lazy accessor.
  • stackscope + setproctitle: already lazy/absent — no change needed.