gentle-flower-25372
06/02/2025, 2:24 PMwide-midnight-78598
06/02/2025, 3:15 PMwide-midnight-78598
06/02/2025, 3:15 PMgentle-flower-25372
06/02/2025, 3:16 PMwide-midnight-78598
06/02/2025, 3:16 PMwide-midnight-78598
06/02/2025, 3:23 PMThat said, there are still things that I'm like wtf, I'm lost how this all worksSuch as?
fresh-mechanic-68429
06/02/2025, 5:41 PMfresh-mechanic-68429
06/02/2025, 5:42 PMgentle-flower-25372
06/02/2025, 5:46 PMsrc/python/pants/backend/project_info/dependents.py:43
How would I go about converting this to rust? What is the interface between python code and rust code?gentle-flower-25372
06/02/2025, 5:47 PMwide-midnight-78598
06/02/2025, 5:51 PMwide-midnight-78598
06/02/2025, 5:52 PMgentle-flower-25372
06/02/2025, 5:52 PMgentle-flower-25372
06/02/2025, 5:52 PMI'd be curious where the time comes from in your repo though - that would be a great dive through the codeAny time you want to pair I can show you. Source is proprietary, but I'd love to provide stats from some command or something or a fork of the pants core.
gentle-flower-25372
06/02/2025, 5:53 PMwide-midnight-78598
06/02/2025, 5:53 PMawait
calls (either using the older Get
syntax, or the newer call-by-name) - that code is essentially fired off to the scheduler - so re-writing that file might not actually change anything.
I'm not saying that for certain, to be clear, but even just timing through the dependents function would give a quick clue if there is any hotspot - or if it's all from the await callsfresh-mechanic-68429
06/02/2025, 5:55 PMhappy-kitchen-89482
06/03/2025, 3:20 PMhappy-kitchen-89482
06/03/2025, 3:21 PMgentle-flower-25372
06/03/2025, 3:21 PMhappy-kitchen-89482
06/03/2025, 3:28 PMgentle-flower-25372
06/03/2025, 3:30 PMgentle-flower-25372
06/03/2025, 3:30 PMhappy-kitchen-89482
06/03/2025, 3:30 PMhappy-kitchen-89482
06/03/2025, 3:31 PMwide-midnight-78598
06/03/2025, 3:59 PM@rule(desc="Map all targets to their dependents", level=LogLevel.DEBUG)
async def map_addresses_to_dependents(all_targets: AllUnexpandedTargets) -> AddressToDependents:
dependencies_per_target = await concurrently(
resolve_dependencies(
DependenciesRequest(
tgt.get(Dependencies), should_traverse_deps_predicate=AlwaysTraverseDeps()
),
**implicitly(),
)
for tgt in all_targets
)
gentle-flower-25372
06/03/2025, 4:12 PMwide-midnight-78598
06/03/2025, 4:13 PMall_targets
variable in that function?gentle-flower-25372
06/03/2025, 4:14 PMpants list //::
how I would count all targets?wide-midnight-78598
06/03/2025, 4:15 PMmain
branch - to maybe identify in more depth what's happening there. If it's launching 15k tasks, that would be something...gentle-flower-25372
06/03/2025, 4:32 PMgentle-flower-25372
06/03/2025, 4:34 PMwide-midnight-78598
06/03/2025, 4:35 PMgentle-flower-25372
06/03/2025, 4:48 PM@rule(desc="Map all targets to their dependents", level=<http://LogLevel.INFO|LogLevel.INFO>)
async def map_addresses_to_dependents(all_targets: AllUnexpandedTargets) -> AddressToDependents:
# Start comprehensive benchmarking
start_time = time.perf_counter()
tracemalloc.start()
num_targets = len(all_targets)
print(f"🔍 BENCHMARK: Starting dependents mapping for {num_targets:,} targets")
print(f"📅 Start time: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}")
# Phase 1: Dependency Resolution
deps_start = time.perf_counter()
print(f"⚡ Phase 1: Starting concurrent dependency resolution...")
dependencies_per_target = await concurrently(
resolve_dependencies(
DependenciesRequest(
tgt.get(Dependencies), should_traverse_deps_predicate=AlwaysTraverseDeps()
),
**implicitly(),
)
for tgt in all_targets
)
deps_end = time.perf_counter()
deps_duration = deps_end - deps_start
print(f"✅ Phase 1 complete: Dependency resolution took {deps_duration:.3f}s ({deps_duration/num_targets*1000:.2f}ms per target)")
# Phase 2: Build dependents mapping
mapping_start = time.perf_counter()
print(f"🗺️ Phase 2: Building dependents mapping...")
address_to_dependents = defaultdict(set)
total_dependencies = 0
max_deps_per_target = 0
target_with_most_deps = None
for tgt, dependencies in zip(all_targets, dependencies_per_target):
deps_count = len(dependencies)
total_dependencies += deps_count
if deps_count > max_deps_per_target:
max_deps_per_target = deps_count
target_with_most_deps = tgt.address
for dependency in dependencies:
address_to_dependents[dependency].add(tgt.address)
mapping_end = time.perf_counter()
mapping_duration = mapping_end - mapping_start
# Phase 3: Create frozen data structures
freeze_start = time.perf_counter()
print(f"🧊 Phase 3: Creating immutable data structures...")
result = AddressToDependents(
FrozenDict(
{
addr: FrozenOrderedSet(dependents)
for addr, dependents in address_to_dependents.items()
}
)
)
freeze_end = time.perf_counter()
freeze_duration = freeze_end - freeze_start
# Final benchmarking and statistics
total_time = time.perf_counter() - start_time
current, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()
# Calculate statistics
avg_deps_per_target = total_dependencies / num_targets if num_targets > 0 else 0
num_unique_dependencies = len(address_to_dependents)
avg_dependents_per_dep = sum(len(deps) for deps in address_to_dependents.values()) / num_unique_dependencies if num_unique_dependencies > 0 else 0
# Print comprehensive benchmark results
print(f"""
📊 BENCHMARK RESULTS - Dependents Mapping Complete
{'='*60}
⏱️ TIMING:
• Total time: {total_time:.3f}s
• Dependency resolution: {deps_duration:.3f}s ({deps_duration/total_time*100:.1f}%)
• Mapping construction: {mapping_duration:.3f}s ({mapping_duration/total_time*100:.1f}%)
• Data structure freezing: {freeze_duration:.3f}s ({freeze_duration/total_time*100:.1f}%)
• Throughput: {num_targets/total_time:.1f} targets/second
💾 MEMORY:
• Current usage: {current / 1024 / 1024:.1f} MB
• Peak usage: {peak / 1024 / 1024:.1f} MB
📈 STATISTICS:
• Total targets: {num_targets:,}
• Total dependencies: {total_dependencies:,}
• Unique dependency targets: {num_unique_dependencies:,}
• Avg deps per target: {avg_deps_per_target:.1f}
• Max deps per target: {max_deps_per_target:,} ({target_with_most_deps})
• Avg dependents per dependency: {avg_dependents_per_dep:.1f}
• Dependency graph density: {total_dependencies/(num_targets*num_targets)*100:.3f}%
🏁 Completed at: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}
{'='*60}
""")
return result
gentle-flower-25372
06/03/2025, 4:49 PMgentle-flower-25372
06/03/2025, 4:52 PMBENCHMARK: Starting dependents mapping for 32,265 targets
gentle-flower-25372
06/03/2025, 4:52 PMwide-midnight-78598
06/03/2025, 4:53 PMgentle-flower-25372
06/03/2025, 4:53 PMgentle-flower-25372
06/03/2025, 4:54 PMgentle-flower-25372
06/03/2025, 4:54 PM📊 BENCHMARK RESULTS - Dependents Mapping Complete
============================================================
⏱{fe0f} TIMING:
• Total time: 150.941s
• Dependency resolution: 150.498s (99.7%)
• Mapping construction: 0.218s (0.1%)
• Data structure freezing: 0.225s (0.1%)
• Throughput: 213.8 targets/second
💾 MEMORY:
• Current usage: 337.5 MB
• Peak usage: 455.9 MB
📈 STATISTICS:
• Total targets: 32,265
• Total dependencies: 133,510
• Unique dependency targets: 29,493
• Avg deps per target: 4.1
• Max deps per target: 2,304 (apps/tileserver-gl/fonts:fonts)
• Avg dependents per dependency: 4.5
• Dependency graph density: 0.013%
🏁 Completed at: 2025-06-03 10:53:41.053
============================================================
gentle-flower-25372
06/03/2025, 4:54 PMwide-midnight-78598
06/03/2025, 4:54 PMMultiGet
work on that many at once? I can't recall - as I last looked through this almost a year ago. Are they all just queued and chewed through by however many threads we have available?gentle-flower-25372
06/03/2025, 5:02 PMgentle-flower-25372
06/03/2025, 5:05 PM📊 DEPENDENCY DISTRIBUTION:
• Top 10 heaviest targets: 2304, 1964, 1863, 676, 638, 630, 624, 585, 559, 538 deps
• Targets with >100 deps: 52
• Targets with >500 deps: 10
• Targets with >1000 deps: 3
gentle-flower-25372
06/03/2025, 5:05 PMhappy-kitchen-89482
06/03/2025, 9:08 PMgentle-flower-25372
06/03/2025, 9:09 PMgentle-flower-25372
06/03/2025, 9:11 PMhappy-kitchen-89482
06/03/2025, 9:21 PMgentle-flower-25372
06/03/2025, 9:21 PMhappy-kitchen-89482
06/03/2025, 9:22 PMhappy-kitchen-89482
06/03/2025, 9:22 PMgentle-flower-25372
06/03/2025, 9:23 PMgentle-flower-25372
06/03/2025, 9:27 PMwide-midnight-78598
06/03/2025, 9:28 PMwide-midnight-78598
06/03/2025, 9:33 PMgentle-flower-25372
06/03/2025, 9:34 PMwide-midnight-78598
06/03/2025, 9:35 PMhappy-kitchen-89482
06/03/2025, 9:44 PMgit log
on those two files should help you find exampleshappy-kitchen-89482
06/03/2025, 9:44 PMhappy-kitchen-89482
06/03/2025, 9:45 PMhigh-magician-46188
06/08/2025, 8:16 AM[2025-06-08T08:00:53.978Z] 91.36s Map all targets to their dependents
.
It looks like we are affected by the same thing and I would like to give a hand in the effort to improve it.
(I'm using Pants v2.24.2)
Is there an action-item for me? (in the mean time, I'll try to also instrument it and get some stats)happy-kitchen-89482
06/10/2025, 10:09 PM