Skip to content

perf(core): defer tracer imports in runnables/base.py to call time#36920

Open
Sydney Runkle (sydney-runkle) wants to merge 9 commits intomasterfrom
sr/deferred-imports
Open

perf(core): defer tracer imports in runnables/base.py to call time#36920
Sydney Runkle (sydney-runkle) wants to merge 9 commits intomasterfrom
sr/deferred-imports

Conversation

@sydney-runkle
Copy link
Copy Markdown
Collaborator

Summary

  • Removes 4 eager top-level tracer imports from runnables/base.py (event_stream, log_stream, root_listeners, _streaming) that were pulled in on every from langchain_core.language_models import BaseChatModel
  • Moves them to TYPE_CHECKING and adds deferred imports at the call sites (astream_log, astream_events, with_listeners, with_alisteners)
  • Keeps _StreamingCallbackHandler at top level since it's a lightweight module needed for isinstance checks

Motivation

The tracer import chain was the dominant cost in from langchain_core.language_models import BaseChatModel:

runnables/base.py
  → tracers.event_stream → tracers.log_stream → tracers.base
  → tracers.schemas → langsmith.run_trees → langsmith.schemas (~32ms self)

This eliminates ~76ms from the import chain, bringing BaseChatModel import from ~291ms down to ~160ms.

Test plan

  • cd libs/core && uv run --group test pytest tests/unit_tests/runnables/ -x -q

🤖 Generated with Claude Code

…rios

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move middleware construction inside benchmarked lambdas for fresh instances
- Rework memory test to observation-only with print output (no hard assertion)
- Add deeply-nested Pydantic schema tool (RouteSchema) to LARGE_TOOLS (15 tools)
- Update docstrings to document '10 accesses per iteration' in schema benchmarks
- Fix bare `_ =` pattern in schema benchmarks (bare expressions)
- Mark memory test with @pytest.mark.benchmark to exclude from normal runs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tion

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
event_stream, log_stream, and root_listeners are only needed by astream_log
and astream_events. Moving these imports inside those methods eliminates ~90ms
from 'from langchain_core.language_models import BaseChatModel' by breaking
the eager load chain into langsmith.schemas.
@github-actions github-actions Bot added core `langchain-core` package issues & PRs dependencies Pull requests that update a dependency file (e.g. `pyproject.toml` or `uv.lock`) internal langchain `langchain` package issues & PRs performance size: M 200-499 LOC labels Apr 21, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 21, 2026

Merging this PR will improve performance by 52.38%

⚡ 7 improved benchmarks
✅ 8 untouched benchmarks
🆕 7 new benchmarks

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime test_import_time[tool] 1,406 ms 959.6 ms +46.52%
WallTime test_import_time[InMemoryVectorStore] 1.5 s 1 s +43.94%
WallTime test_import_time[BaseChatModel] 1,373.2 ms 962.6 ms +42.65%
WallTime test_import_time[ChatPromptTemplate] 1.6 s 1.1 s +52.38%
WallTime test_import_time[Runnable] 1,270.7 ms 857.3 ms +48.22%
WallTime test_import_time[PydanticOutputParser] 1,393.9 ms 953.3 ms +46.23%
WallTime test_import_time[RunnableLambda] 1,268.2 ms 857.1 ms +47.96%
🆕 Simulation test_create_agent_medium_tools N/A 10.6 ms N/A
🆕 Simulation test_tool_call_schema_repeated_access N/A 20.1 µs N/A
🆕 Simulation test_tool_args_repeated_access N/A 19.9 µs N/A
🆕 Simulation test_create_agent_small_tools N/A 9.6 ms N/A
🆕 Simulation test_create_agent_large_tools_with_middleware N/A 19.3 ms N/A
🆕 Simulation test_create_agent_large_tools_memory N/A 81.3 ms N/A
🆕 Simulation test_create_agent_large_tools N/A 13.5 ms N/A

Comparing sr/deferred-imports (0545fee) with master (fb6ab99)1

Open in CodSpeed

Footnotes

  1. No successful run was found on master (acc5498) during the generation of this report, so fb6ab99 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core `langchain-core` package issues & PRs dependencies Pull requests that update a dependency file (e.g. `pyproject.toml` or `uv.lock`) internal langchain `langchain` package issues & PRs performance size: M 200-499 LOC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant