Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: Intern string constants #1797

Merged
merged 2 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 32 additions & 28 deletions libs/langgraph/langgraph/constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import sys

Check notice on line 1 in libs/langgraph/langgraph/constants.py

View workflow job for this annotation

GitHub Actions / benchmark

Benchmark results

......................................... fanout_to_subgraph_10x: Mean +- std dev: 60.3 ms +- 1.6 ms ......................................... WARNING: the benchmark result may be unstable * the standard deviation (8.36 ms) is 14% of the mean (59.1 ms) Try to rerun the benchmark with more runs, values and/or loops. Run 'python -m pyperf system tune' command to reduce the system jitter. Use pyperf stats, pyperf dump and pyperf hist to analyze results. Use --quiet option to hide these warnings. fanout_to_subgraph_10x_sync: Mean +- std dev: 59.1 ms +- 8.4 ms ......................................... fanout_to_subgraph_10x_checkpoint: Mean +- std dev: 78.8 ms +- 1.3 ms ......................................... fanout_to_subgraph_10x_checkpoint_sync: Mean +- std dev: 83.4 ms +- 0.8 ms ......................................... fanout_to_subgraph_100x: Mean +- std dev: 599 ms +- 12 ms ......................................... fanout_to_subgraph_100x_sync: Mean +- std dev: 511 ms +- 6 ms ......................................... fanout_to_subgraph_100x_checkpoint: Mean +- std dev: 847 ms +- 25 ms ......................................... fanout_to_subgraph_100x_checkpoint_sync: Mean +- std dev: 801 ms +- 11 ms ......................................... react_agent_10x: Mean +- std dev: 42.1 ms +- 3.8 ms ......................................... react_agent_10x_sync: Mean +- std dev: 29.9 ms +- 0.4 ms ......................................... react_agent_10x_checkpoint: Mean +- std dev: 53.4 ms +- 1.5 ms ......................................... react_agent_10x_checkpoint_sync: Mean +- std dev: 43.2 ms +- 3.4 ms ......................................... react_agent_100x: Mean +- std dev: 417 ms +- 6 ms ......................................... react_agent_100x_sync: Mean +- std dev: 333 ms +- 4 ms ......................................... react_agent_100x_checkpoint: Mean +- std dev: 937 ms +- 15 ms ......................................... react_agent_100x_checkpoint_sync: Mean +- std dev: 834 ms +- 16 ms ......................................... wide_state_25x300: Mean +- std dev: 20.4 ms +- 0.3 ms ......................................... wide_state_25x300_sync: Mean +- std dev: 12.9 ms +- 0.2 ms ......................................... wide_state_25x300_checkpoint: Mean +- std dev: 240 ms +- 8 ms ......................................... wide_state_25x300_checkpoint_sync: Mean +- std dev: 238 ms +- 16 ms ......................................... wide_state_15x600: Mean +- std dev: 23.6 ms +- 0.3 ms ......................................... wide_state_15x600_sync: Mean +- std dev: 14.8 ms +- 0.2 ms ......................................... wide_state_15x600_checkpoint: Mean +- std dev: 414 ms +- 11 ms ......................................... wide_state_15x600_checkpoint_sync: Mean +- std dev: 418 ms +- 20 ms ......................................... wide_state_9x1200: Mean +- std dev: 23.7 ms +- 0.4 ms ......................................... wide_state_9x1200_sync: Mean +- std dev: 14.9 ms +- 0.4 ms ......................................... wide_state_9x1200_checkpoint: Mean +- std dev: 268 ms +- 8 ms ......................................... wide_state_9x1200_checkpoint_sync: Mean +- std dev: 269 ms +- 16 ms

Check notice on line 1 in libs/langgraph/langgraph/constants.py

View workflow job for this annotation

GitHub Actions / benchmark

Comparison against main

+----------------------------------------+---------+-----------------------+ | Benchmark | main | changes | +========================================+=========+=======================+ | react_agent_100x_sync | 343 ms | 333 ms: 1.03x faster | +----------------------------------------+---------+-----------------------+ | wide_state_15x600_checkpoint | 426 ms | 414 ms: 1.03x faster | +----------------------------------------+---------+-----------------------+ | wide_state_9x1200_checkpoint | 274 ms | 268 ms: 1.02x faster | +----------------------------------------+---------+-----------------------+ | wide_state_15x600 | 24.1 ms | 23.6 ms: 1.02x faster | +----------------------------------------+---------+-----------------------+ | wide_state_25x300 | 20.8 ms | 20.4 ms: 1.02x faster | +----------------------------------------+---------+-----------------------+ | wide_state_9x1200 | 24.1 ms | 23.7 ms: 1.02x faster | +----------------------------------------+---------+-----------------------+ | wide_state_25x300_checkpoint | 243 ms | 240 ms: 1.01x faster | +----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_10x_checkpoint | 79.5 ms | 78.8 ms: 1.01x faster | +----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_10x_checkpoint_sync | 84.1 ms | 83.4 ms: 1.01x faster | +----------------------------------------+---------+-----------------------+ | react_agent_100x | 419 ms | 417 ms: 1.01x faster | +----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_100x_sync | 508 ms | 511 ms: 1.00x slower | +----------------------------------------+---------+-----------------------+ | react_agent_100x_checkpoint_sync | 827 ms | 834 ms: 1.01x slower | +----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_10x | 59.8 ms | 60.3 ms: 1.01x slower | +----------------------------------------+---------+-----------------------+ | wide_state_9x1200_sync | 14.7 ms | 14.9 ms: 1.01x slower | +----------------------------------------+---------+-----------------------+ | react_agent_100x_checkpoint | 926 ms | 937 ms: 1.01x slower | +----------------------------------------+---------+-----------------------+ | wide_state_9x1200_checkpoint_sync | 264 ms | 269 ms: 1.02x slower | +----------------------------------------+---------+-----------------------+ | wide_state_25x300_checkpoint_sync | 234 ms | 238 ms: 1.02x slower | +----------------------------------------+---------+-----------------------+ | react_agent_10x | 39.6 ms | 42.1 ms: 1.06x slower | +----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_100x | 554 ms | 599 ms: 1.08x slower | +----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_100x_checkpoint | 767 ms | 847 ms: 1.11x slower | +----------------------------------------+---------+-----------------------+ | Geometric mean | (ref) | 1.00x slower | +----------------------------------------+---------+-----------------------+ Benchmark hidden because not significant (8): react_agent_10x_checkpoint_sync, fanout_to_subgraph_10x_sync, react_agent_10x_sync, wide_state_15x600_sync, wide_state_15x600_checkpoint_sync, fanout_to_subgraph_100x_checkpoint_sync, react_agent_10x_checkpoint, wide_state_25x300_sync
from types import MappingProxyType
from typing import Any, Mapping
from typing import Any, Literal, Mapping, cast

from langgraph.types import Interrupt, Send # noqa: F401

Expand All @@ -11,67 +12,69 @@
EMPTY_SEQ: tuple[str, ...] = tuple()

# --- Public constants ---
TAG_HIDDEN = "langsmith:hidden"
TAG_HIDDEN = sys.intern("langsmith:hidden")
# tag to hide a node/edge from certain tracing/streaming environments
START = "__start__"
START = sys.intern("__start__")
# the first (maybe virtual) node in graph-style Pregel
END = "__end__"
END = sys.intern("__end__")
# the last (maybe virtual) node in graph-style Pregel

# --- Reserved write keys ---
INPUT = "__input__"
INPUT = sys.intern("__input__")
# for values passed as input to the graph
INTERRUPT = "__interrupt__"
INTERRUPT = sys.intern("__interrupt__")
# for dynamic interrupts raised by nodes
ERROR = "__error__"
ERROR = sys.intern("__error__")
# for errors raised by nodes
NO_WRITES = "__no_writes__"
NO_WRITES = sys.intern("__no_writes__")
# marker to signal node didn't write anything
SCHEDULED = "__scheduled__"
SCHEDULED = sys.intern("__scheduled__")
# marker to signal node was scheduled (in distributed mode)
TASKS = "__pregel_tasks"
TASKS = sys.intern("__pregel_tasks")
# for Send objects returned by nodes/edges, corresponds to PUSH below

# --- Reserved config.configurable keys ---
CONFIG_KEY_SEND = "__pregel_send"
CONFIG_KEY_SEND = sys.intern("__pregel_send")
# holds the `write` function that accepts writes to state/edges/reserved keys
CONFIG_KEY_READ = "__pregel_read"
CONFIG_KEY_READ = sys.intern("__pregel_read")
# holds the `read` function that returns a copy of the current state
CONFIG_KEY_CHECKPOINTER = "__pregel_checkpointer"
CONFIG_KEY_CHECKPOINTER = sys.intern("__pregel_checkpointer")
# holds a `BaseCheckpointSaver` passed from parent graph to child graphs
CONFIG_KEY_STREAM = "__pregel_stream"
CONFIG_KEY_STREAM = sys.intern("__pregel_stream")
# holds a `StreamProtocol` passed from parent graph to child graphs
CONFIG_KEY_STREAM_WRITER = "__pregel_stream_writer"
CONFIG_KEY_STREAM_WRITER = sys.intern("__pregel_stream_writer")
# holds a `StreamWriter` for stream_mode=custom
CONFIG_KEY_STORE = "__pregel_store"
CONFIG_KEY_STORE = sys.intern("__pregel_store")
# holds a `BaseStore` made available to managed values
CONFIG_KEY_RESUMING = "__pregel_resuming"
CONFIG_KEY_RESUMING = sys.intern("__pregel_resuming")
# holds a boolean indicating if subgraphs should resume from a previous checkpoint
CONFIG_KEY_TASK_ID = "__pregel_task_id"
CONFIG_KEY_TASK_ID = sys.intern("__pregel_task_id")
# holds the task ID for the current task
CONFIG_KEY_DEDUPE_TASKS = "__pregel_dedupe_tasks"
CONFIG_KEY_DEDUPE_TASKS = sys.intern("__pregel_dedupe_tasks")
# holds a boolean indicating if tasks should be deduplicated (for distributed mode)
CONFIG_KEY_ENSURE_LATEST = "__pregel_ensure_latest"
CONFIG_KEY_ENSURE_LATEST = sys.intern("__pregel_ensure_latest")
# holds a boolean indicating whether to assert the requested checkpoint is the latest
# (for distributed mode)
CONFIG_KEY_DELEGATE = "__pregel_delegate"
CONFIG_KEY_DELEGATE = sys.intern("__pregel_delegate")
# holds a boolean indicating whether to delegate subgraphs (for distributed mode)
CONFIG_KEY_CHECKPOINT_MAP = "checkpoint_map"
CONFIG_KEY_CHECKPOINT_MAP = sys.intern("checkpoint_map")
# holds a mapping of checkpoint_ns -> checkpoint_id for parent graphs
CONFIG_KEY_CHECKPOINT_ID = "checkpoint_id"
CONFIG_KEY_CHECKPOINT_ID = sys.intern("checkpoint_id")
# holds the current checkpoint_id, if any
CONFIG_KEY_CHECKPOINT_NS = "checkpoint_ns"
CONFIG_KEY_CHECKPOINT_NS = sys.intern("checkpoint_ns")
# holds the current checkpoint_ns, "" for root graph

# --- Other constants ---
PUSH = "__pregel_push"
PUSH = sys.intern("__pregel_push")
# denotes push-style tasks, ie. those created by Send objects
PULL = "__pregel_pull"
PULL = sys.intern("__pregel_pull")
# denotes pull-style tasks, ie. those triggered by edges
NS_SEP = "|"
NS_SEP = sys.intern("|")
# for checkpoint_ns, separates each level (ie. graph|subgraph|subsubgraph)
NS_END = ":"
NS_END = sys.intern(":")
# for checkpoint_ns, for each level, separates the namespace from the task_id
CONF = cast(Literal["configurable"], sys.intern("configurable"))
# key for the configurable dict in RunnableConfig

RESERVED = {
TAG_HIDDEN,
Expand Down Expand Up @@ -103,4 +106,5 @@
PULL,
NS_SEP,
NS_END,
CONF,
}
6 changes: 3 additions & 3 deletions libs/langgraph/langgraph/managed/shared_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from langchain_core.runnables import RunnableConfig
from typing_extensions import NotRequired, Required, Self

from langgraph.constants import CONFIG_KEY_STORE
from langgraph.constants import CONF, CONFIG_KEY_STORE
from langgraph.errors import InvalidUpdateError
from langgraph.managed.base import (
ChannelKeyPlaceholder,
Expand Down Expand Up @@ -83,10 +83,10 @@ def __init__(
raise ValueError("SharedValue must be a dict")
self.scope = scope
self.value: Value = {}
self.store = cast(BaseStore, config["configurable"].get(CONFIG_KEY_STORE))
self.store = cast(BaseStore, config[CONF].get(CONFIG_KEY_STORE))
if self.store is None:
pass
elif scope_value := config["configurable"].get(self.scope):
elif scope_value := config[CONF].get(self.scope):
self.ns = f"scoped:{scope}:{key}:{scope_value}"
else:
raise ValueError(
Expand Down
Loading
Loading