Skip to content

Commit 4b8471b

Browse files
tenpercentclaude
andcommitted
Use integer microseconds instead of float milliseconds
Performance and precision improvements: - Parse durations as integers (microseconds) instead of floats (milliseconds) - Accumulate all durations in microseconds for better precision - Use integer division for average calculations - Avoid floating point arithmetic throughout data processing Template updates: - Add us_to_ms and us_to_s Jinja2 filters for display formatting - Convert microseconds to milliseconds/seconds only for display - Update all template fields to use conversion filters - Maintain precision in calculations, format only for output Benefits: - Better precision (no floating point rounding errors) - Faster processing (integer arithmetic) - Matches native trace file format (microseconds) - Cleaner separation of storage vs display formatting Co-Authored-By: Claude <noreply@anthropic.com>
1 parent cef3e86 commit 4b8471b

2 files changed

Lines changed: 27 additions & 20 deletions

File tree

.claude/skills/analyze_build_trace.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ def process_events(data):
5555
"""Process trace events and extract template instantiation statistics."""
5656
print('Processing events...')
5757

58-
template_stats = defaultdict(lambda: {'count': 0, 'total_dur': 0.0})
59-
phase_stats = defaultdict(float)
58+
template_stats = defaultdict(lambda: {'count': 0, 'total_dur': 0})
59+
phase_stats = defaultdict(int)
6060
top_individual = []
6161

6262
for event in data.get('traceEvents', []):
6363
name = event.get('name', '')
64-
dur = event.get('dur', 0) / 1000.0 # Convert to milliseconds
64+
dur = int(event.get('dur', 0)) # Keep as integer microseconds
6565

6666
if name and dur > 0:
6767
phase_stats[name] += dur
@@ -107,7 +107,7 @@ def prepare_template_data(template_stats, phase_stats, top_individual):
107107
templates_by_time.append((name, {
108108
'count': stats['count'],
109109
'total_dur': stats['total_dur'],
110-
'avg': stats['total_dur'] / stats['count'] if stats['count'] > 0 else 0,
110+
'avg': stats['total_dur'] // stats['count'] if stats['count'] > 0 else 0,
111111
'pct': 100 * stats['total_dur'] / total_template_time if total_template_time > 0 else 0
112112
}))
113113

@@ -117,7 +117,7 @@ def prepare_template_data(template_stats, phase_stats, top_individual):
117117
templates_by_count.append((name, {
118118
'count': stats['count'],
119119
'total_dur': stats['total_dur'],
120-
'avg': stats['total_dur'] / stats['count'] if stats['count'] > 0 else 0
120+
'avg': stats['total_dur'] // stats['count'] if stats['count'] > 0 else 0
121121
}))
122122

123123
# Add friendly type names to individual instantiations
@@ -165,9 +165,19 @@ def pad(value, length):
165165
"""Pad string to specified length."""
166166
return f'{value:<{length}}'
167167

168+
def us_to_ms(value):
169+
"""Convert microseconds to milliseconds."""
170+
return value / 1000.0
171+
172+
def us_to_s(value):
173+
"""Convert microseconds to seconds."""
174+
return value / 1000000.0
175+
168176
env.filters['format_number'] = format_number
169177
env.filters['truncate'] = truncate
170178
env.filters['pad'] = pad
179+
env.filters['us_to_ms'] = us_to_ms
180+
env.filters['us_to_s'] = us_to_s
171181

172182
return env
173183

@@ -183,9 +193,6 @@ def generate_report(env, data, args, total_events):
183193
target=args['target'],
184194
granularity=args['granularity'],
185195
build_time=args['build_time'],
186-
trace_time_sec=f'{data["total_trace_time"] / 1000:.1f}',
187-
template_time_sec=f'{data["total_template_time"] / 1000:.1f}',
188-
template_pct=f'{100 * data["total_template_time"] / data["total_trace_time"]:.1f}',
189196
total_events=total_events,
190197
total_instantiations=data['total_inst'],
191198
unique_families=data['unique_families'],
@@ -196,7 +203,7 @@ def generate_report(env, data, args, total_events):
196203
templates_by_time=data['templates_by_time'],
197204
templates_by_count=data['templates_by_count'],
198205
median_count=data['median_count'],
199-
top10_pct=f'{data["top10_pct"]:.1f}'
206+
top10_pct=data['top10_pct']
200207
)
201208

202209
return report_content

.claude/skills/templates/build_analysis_report.md.jinja

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
## Executive Summary
88

99
- **Wall Clock Time:** {{ build_time }} seconds
10-
- **Trace Time:** {{ trace_time_sec }} seconds
11-
- **Template Instantiation Time:** {{ template_time_sec }} seconds ({{ template_pct }}% of trace)
10+
- **Trace Time:** {{ total_trace_time|us_to_s|round(1) }} seconds
11+
- **Template Instantiation Time:** {{ total_template_time|us_to_s|round(1) }} seconds ({{ (100 * total_template_time / total_trace_time)|round(1) }}% of trace)
1212
- **Total Events Captured:** {{ total_events|format_number }}
1313
- **Total Template Instantiations:** {{ total_instantiations|format_number }}
1414
- **Unique Template Families:** {{ unique_families }}
@@ -18,47 +18,47 @@
1818
| Phase | Time (ms) | Time (s) | % of Total |
1919
|-------|-----------|----------|------------|
2020
{% for phase, dur in phases[:20] -%}
21-
| {{ phase|pad(40) }} | {{ "%9.2f"|format(dur) }} | {{ "%8.2f"|format(dur/1000) }} | {{ "%9.1f"|format(100 * dur / total_trace_time) }}% |
21+
| {{ phase|pad(40) }} | {{ "%9.2f"|format(dur|us_to_ms) }} | {{ "%8.2f"|format(dur|us_to_s) }} | {{ "%9.1f"|format(100 * dur / total_trace_time) }}% |
2222
{% endfor %}
2323

2424
## Top 30 Most Expensive Individual Instantiations
2525

2626
| Rank | Template | Type | Time (ms) |
2727
|------|----------|------|-----------|
2828
{% for inst in top_individual[:30] -%}
29-
| {{ "%4d"|format(loop.index) }} | {{ inst.detail|truncate(70) }} | {{ inst.inst_type|pad(5) }} | {{ "%9.2f"|format(inst.dur) }} |
29+
| {{ "%4d"|format(loop.index) }} | {{ inst.detail|truncate(70) }} | {{ inst.inst_type|pad(5) }} | {{ "%9.2f"|format(inst.dur|us_to_ms) }} |
3030
{% endfor %}
3131

3232
## Template Families by Total Time (Top 50)
3333

3434
| Rank | Template Family | Count | Total (ms) | Avg (ms) | % of Total |
3535
|------|-----------------|-------|------------|----------|------------|
3636
{% for name, stats in templates_by_time[:50] -%}
37-
| {{ "%4d"|format(loop.index) }} | {{ name|truncate(43)|pad(43) }} | {{ "%5d"|format(stats.count) }} | {{ "%10.2f"|format(stats.total_dur) }} | {{ "%8.2f"|format(stats.avg) }} | {{ "%9.1f"|format(stats.pct) }}% |
37+
| {{ "%4d"|format(loop.index) }} | {{ name|truncate(43)|pad(43) }} | {{ "%5d"|format(stats.count) }} | {{ "%10.2f"|format(stats.total_dur|us_to_ms) }} | {{ "%8.2f"|format(stats.avg|us_to_ms) }} | {{ "%9.1f"|format(stats.pct) }}% |
3838
{% endfor %}
3939

4040
## Template Families by Instantiation Count (Top 50)
4141

4242
| Rank | Template Family | Count | Total (ms) | Avg (ms) |
4343
|------|-----------------|-------|------------|----------|
4444
{% for name, stats in templates_by_count[:50] -%}
45-
| {{ "%4d"|format(loop.index) }} | {{ name|truncate(43)|pad(43) }} | {{ "%5d"|format(stats.count) }} | {{ "%10.2f"|format(stats.total_dur) }} | {{ "%8.2f"|format(stats.avg) }} |
45+
| {{ "%4d"|format(loop.index) }} | {{ name|truncate(43)|pad(43) }} | {{ "%5d"|format(stats.count) }} | {{ "%10.2f"|format(stats.total_dur|us_to_ms) }} | {{ "%8.2f"|format(stats.avg|us_to_ms) }} |
4646
{% endfor %}
4747

4848
## Key Insights
4949

5050
### 1. Template Instantiation Impact
51-
- Template instantiation accounts for {{ template_pct }}% of total trace time
51+
- Template instantiation accounts for {{ (100 * total_template_time / total_trace_time)|round(1) }}% of total trace time
5252
{% if unique_families >= 10 -%}
53-
- Top 10 template families account for {{ top10_pct }}% of instantiation time
53+
- Top 10 template families account for {{ top10_pct|round(1) }}% of instantiation time
5454
{% endif %}
5555

5656
### 2. Most Expensive Templates
5757
{% if templates_by_time|length > 0 -%}
58-
- **{{ templates_by_time[0][0] }}**: {{ templates_by_time[0][1].count|format_number }} instantiations, {{ "%.2f"|format(templates_by_time[0][1].total_dur/1000) }}s total
58+
- **{{ templates_by_time[0][0] }}**: {{ templates_by_time[0][1].count|format_number }} instantiations, {{ (templates_by_time[0][1].total_dur|us_to_s)|round(2) }}s total
5959
{% endif -%}
6060
{% if templates_by_time|length > 1 -%}
61-
- **{{ templates_by_time[1][0] }}**: {{ templates_by_time[1][1].count|format_number }} instantiations, {{ "%.2f"|format(templates_by_time[1][1].avg) }}ms average
61+
- **{{ templates_by_time[1][0] }}**: {{ templates_by_time[1][1].count|format_number }} instantiations, {{ (templates_by_time[1][1].avg|us_to_ms)|round(2) }}ms average
6262
{% endif %}
6363

6464
## Optimization Recommendations
@@ -83,7 +83,7 @@
8383
- **Total Unique Templates:** {{ unique_families }}
8484
- **Total Instantiations:** {{ total_instantiations|format_number }}
8585
{% if total_instantiations > 0 -%}
86-
- **Average Instantiation Time:** {{ "%.3f"|format(total_template_time/total_instantiations) }}ms
86+
- **Average Instantiation Time:** {{ ((total_template_time // total_instantiations)|us_to_ms)|round(3) }}ms
8787
{% endif -%}
8888
{% if unique_families > 0 -%}
8989
- **Median Template Family Count:** {{ median_count }}

0 commit comments

Comments
 (0)