diff --git a/.github/workflows/pack-perf.yml b/.github/workflows/pack-perf.yml index 875d5bd370..a957739076 100644 --- a/.github/workflows/pack-perf.yml +++ b/.github/workflows/pack-perf.yml @@ -71,7 +71,7 @@ jobs: - name: Analyze Traces run: | - python3 agents/tools/analyze_trace.py .trace/trace_antd.json .trace/report_antd.md + TRACE_PROJECT=examples/with-antd python3 agents/tools/analyze_trace.py .trace/trace_antd.json .trace/report_antd.md # Prepare PR comment content echo "## 📊 Performance Benchmark Report (with-antd)" > .trace/pr_comment.md cat .trace/report_antd.md >> .trace/pr_comment.md diff --git a/agents/tools/analyze_trace.py b/agents/tools/analyze_trace.py index a254e30b82..3650f0899b 100644 --- a/agents/tools/analyze_trace.py +++ b/agents/tools/analyze_trace.py @@ -12,7 +12,7 @@ from collections import defaultdict from datetime import datetime -def analyze_trace(trace_path, output_path): +def analyze_trace(trace_path, output_path, override_project_name=None): """Analyze Chrome Trace and generate performance report following the protocol""" print(f"📊 Loading trace: {trace_path}") @@ -21,6 +21,9 @@ def analyze_trace(trace_path, output_path): events = data if isinstance(data, list) else data.get("traceEvents", []) print(f"✅ Analyzing {len(events):,} events...") + + # Try to infer project name + project_name = override_project_name or os.environ.get("TRACE_PROJECT") or "Unknown Project" # Initialize metrics min_ts, max_ts = float('inf'), float('-inf') @@ -130,18 +133,6 @@ def analyze_trace(trace_path, output_path): trace_file = os.path.basename(trace_path) trace_size_gb = os.path.getsize(trace_path) / (1024**3) - # Try to infer project name - project_name = "Unknown Project" - abs_path = os.path.abspath(trace_path) - path_parts = abs_path.split(os.sep) - if "examples" in path_parts: - try: - idx = path_parts.index("examples") - if idx + 1 < len(path_parts): - project_name = f"examples/{path_parts[idx+1]}" - except ValueError: - pass - # Pre-calculate derived metrics max_thread_work = max(thread_work, 1) # Avoid division by zero total_tasks_safe = max(total_tasks, 1) @@ -336,14 +327,15 @@ def analyze_trace(trace_path, output_path): if __name__ == "__main__": if len(sys.argv) < 3: - print("Usage: python3 analyze_trace.py ") + print("Usage: python3 analyze_trace.py [project_name]") sys.exit(1) trace_file = sys.argv[1] report_file = sys.argv[2] + override_project_name = sys.argv[3] if len(sys.argv) > 3 else None if not os.path.exists(trace_file): print(f"Error: Trace file not found: {trace_file}") sys.exit(1) - analyze_trace(trace_file, report_file) + analyze_trace(trace_file, report_file, override_project_name) diff --git a/agents/utoopack-performance-agent.md b/agents/utoopack-performance-agent.md index a915912c6f..e4b35316a7 100644 --- a/agents/utoopack-performance-agent.md +++ b/agents/utoopack-performance-agent.md @@ -97,7 +97,8 @@ Follow this tiered hierarchy. Solve P0 before descending to P1, as high-level sc --- ## 🚀 Step 3: Actionable Diagnostic Workflow -1. **Quantitative Baseline**: Run the summary script `python3 agents/tools/analyze_trace.py ` to list Top 20 tasks by `count` and `sum(duration)`. +1. **Quantitative Baseline**: Run the summary script with the **`TRACE_PROJECT`** environment variable to identify the build target. + - *Command*: `TRACE_PROJECT=examples/with-antd python3 agents/tools/analyze_trace.py ` 2. **Qualitative Timeline Scan**: Open the trace in `chrome://tracing` or `edge://tracing`. Look for "Wall-like" structures (Parallelism) vs "Staircase" structures (Serialism). 3. **Causal Attribution**: Identify the `Parent Span` of the top bottlenecks to understand *why* they were invoked. 4. **Final Reporting**: Summarize findings and save the report to `./agents/reports/utoopack_performance_report_YYYYMMDD_HHMMSS.md`. Include specific Tiered signals and recommended actions.