-
Notifications
You must be signed in to change notification settings - Fork 470
feat(profiling): support Python 3.14 #15546
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
base: main
Are you sure you want to change the base?
Conversation
|
|
Bootstrap import analysisComparison of import times between this PR and base. SummaryThe average import time from this PR is: 252 ± 5 ms. The average import time from base is: 255 ± 4 ms. The import time difference between this PR and base is: -3.1 ± 0.2 ms. Import time breakdownThe following import paths have shrunk:
|
Performance SLOsComparing candidate taegyunkim/prof-12435-py314 (cc21de7) with baseline main (7bff945) 📈 Performance Regressions (2 suites)📈 iastaspectsospath - 24/24✅ ospathbasename_aspectTime: ✅ 5.148µs (SLO: <10.000µs 📉 -48.5%) vs baseline: 📈 +21.4% Memory: ✅ 38.653MB (SLO: <41.000MB -5.7%) vs baseline: +5.0% ✅ ospathbasename_noaspectTime: ✅ 1.086µs (SLO: <10.000µs 📉 -89.1%) vs baseline: +0.6% Memory: ✅ 38.555MB (SLO: <41.000MB -6.0%) vs baseline: +4.9% ✅ ospathjoin_aspectTime: ✅ 6.118µs (SLO: <10.000µs 📉 -38.8%) vs baseline: +1.6% Memory: ✅ 38.594MB (SLO: <41.000MB -5.9%) vs baseline: +5.4% ✅ ospathjoin_noaspectTime: ✅ 2.301µs (SLO: <10.000µs 📉 -77.0%) vs baseline: +0.6% Memory: ✅ 38.339MB (SLO: <41.000MB -6.5%) vs baseline: +4.2% ✅ ospathnormcase_aspectTime: ✅ 3.479µs (SLO: <10.000µs 📉 -65.2%) vs baseline: +0.2% Memory: ✅ 38.594MB (SLO: <41.000MB -5.9%) vs baseline: +5.0% ✅ ospathnormcase_noaspectTime: ✅ 0.575µs (SLO: <10.000µs 📉 -94.3%) vs baseline: +0.3% Memory: ✅ 38.614MB (SLO: <41.000MB -5.8%) vs baseline: +5.0% ✅ ospathsplit_aspectTime: ✅ 4.843µs (SLO: <10.000µs 📉 -51.6%) vs baseline: -0.2% Memory: ✅ 38.516MB (SLO: <41.000MB -6.1%) vs baseline: +4.8% ✅ ospathsplit_noaspectTime: ✅ 1.594µs (SLO: <10.000µs 📉 -84.1%) vs baseline: +0.1% Memory: ✅ 38.535MB (SLO: <41.000MB -6.0%) vs baseline: +4.4% ✅ ospathsplitdrive_aspectTime: ✅ 3.652µs (SLO: <10.000µs 📉 -63.5%) vs baseline: -1.4% Memory: ✅ 38.594MB (SLO: <41.000MB -5.9%) vs baseline: +5.0% ✅ ospathsplitdrive_noaspectTime: ✅ 0.705µs (SLO: <10.000µs 📉 -93.0%) vs baseline: +0.6% Memory: ✅ 38.535MB (SLO: <41.000MB -6.0%) vs baseline: +4.7% ✅ ospathsplitext_aspectTime: ✅ 4.585µs (SLO: <10.000µs 📉 -54.1%) vs baseline: +0.6% Memory: ✅ 38.614MB (SLO: <41.000MB -5.8%) vs baseline: +4.9% ✅ ospathsplitext_noaspectTime: ✅ 1.390µs (SLO: <10.000µs 📉 -86.1%) vs baseline: +0.5% Memory: ✅ 38.594MB (SLO: <41.000MB -5.9%) vs baseline: +4.8% 📈 telemetryaddmetric - 30/30✅ 1-count-metric-1-timesTime: ✅ 3.326µs (SLO: <20.000µs 📉 -83.4%) vs baseline: 📈 +15.2% Memory: ✅ 34.918MB (SLO: <35.500MB 🟡 -1.6%) vs baseline: +4.5% ✅ 1-count-metrics-100-timesTime: ✅ 198.610µs (SLO: <220.000µs -9.7%) vs baseline: -1.0% Memory: ✅ 34.937MB (SLO: <35.500MB 🟡 -1.6%) vs baseline: +4.7% ✅ 1-distribution-metric-1-timesTime: ✅ 3.178µs (SLO: <20.000µs 📉 -84.1%) vs baseline: -0.4% Memory: ✅ 34.662MB (SLO: <35.500MB -2.4%) vs baseline: +3.6% ✅ 1-distribution-metrics-100-timesTime: ✅ 213.075µs (SLO: <230.000µs -7.4%) vs baseline: -1.5% Memory: ✅ 35.036MB (SLO: <35.500MB 🟡 -1.3%) vs baseline: +4.8% ✅ 1-gauge-metric-1-timesTime: ✅ 2.156µs (SLO: <20.000µs 📉 -89.2%) vs baseline: -0.5% Memory: ✅ 34.977MB (SLO: <35.500MB 🟡 -1.5%) vs baseline: +4.7% ✅ 1-gauge-metrics-100-timesTime: ✅ 137.541µs (SLO: <150.000µs -8.3%) vs baseline: +0.8% Memory: ✅ 35.036MB (SLO: <35.500MB 🟡 -1.3%) ✅ 1-rate-metric-1-timesTime: ✅ 2.997µs (SLO: <20.000µs 📉 -85.0%) vs baseline: -1.0% Memory: ✅ 34.819MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.3% ✅ 1-rate-metrics-100-timesTime: ✅ 212.490µs (SLO: <250.000µs 📉 -15.0%) vs baseline: -1.6% Memory: ✅ 34.918MB (SLO: <35.500MB 🟡 -1.6%) vs baseline: +4.5% ✅ 100-count-metrics-100-timesTime: ✅ 20.099ms (SLO: <22.000ms -8.6%) vs baseline: +0.8% Memory: ✅ 34.760MB (SLO: <35.500MB -2.1%) vs baseline: +5.0% ✅ 100-distribution-metrics-100-timesTime: ✅ 2.211ms (SLO: <2.550ms 📉 -13.3%) vs baseline: -0.3% Memory: ✅ 35.055MB (SLO: <35.500MB 🟡 -1.3%) vs baseline: +4.8% ✅ 100-gauge-metrics-100-timesTime: ✅ 1.411ms (SLO: <1.550ms -8.9%) vs baseline: +0.5% Memory: ✅ 34.721MB (SLO: <35.500MB -2.2%) vs baseline: +4.8% ✅ 100-rate-metrics-100-timesTime: ✅ 2.183ms (SLO: <2.550ms 📉 -14.4%) vs baseline: ~same Memory: ✅ 34.721MB (SLO: <35.500MB -2.2%) vs baseline: +4.8% ✅ flush-1-metricTime: ✅ 4.540µs (SLO: <20.000µs 📉 -77.3%) vs baseline: +0.3% Memory: ✅ 35.095MB (SLO: <35.500MB 🟡 -1.1%) vs baseline: +5.1% ✅ flush-100-metricsTime: ✅ 173.311µs (SLO: <250.000µs 📉 -30.7%) vs baseline: -0.2% Memory: ✅ 35.134MB (SLO: <35.500MB 🟡 -1.0%) vs baseline: +4.9% ✅ flush-1000-metricsTime: ✅ 2.174ms (SLO: <2.500ms 📉 -13.0%) vs baseline: -0.1% Memory: ✅ 35.920MB (SLO: <36.500MB 🟡 -1.6%) vs baseline: +4.6% 🟡 Near SLO Breach (14 suites)🟡 djangosimple - 30/30✅ appsecTime: ✅ 19.653ms (SLO: <22.300ms 📉 -11.9%) vs baseline: +0.4% Memory: ✅ 68.203MB (SLO: <70.500MB -3.3%) vs baseline: +4.9% ✅ exception-replay-enabledTime: ✅ 1.364ms (SLO: <1.450ms -5.9%) vs baseline: +0.5% Memory: ✅ 66.249MB (SLO: <67.500MB 🟡 -1.9%) vs baseline: +4.8% ✅ iastTime: ✅ 19.632ms (SLO: <22.250ms 📉 -11.8%) vs baseline: +0.6% Memory: ✅ 68.243MB (SLO: <70.000MB -2.5%) vs baseline: +5.0% ✅ profilerTime: ✅ 15.471ms (SLO: <16.550ms -6.5%) vs baseline: +0.6% Memory: ✅ 56.436MB (SLO: <57.500MB 🟡 -1.8%) vs baseline: +5.1% ✅ resource-renamingTime: ✅ 19.547ms (SLO: <21.750ms 📉 -10.1%) vs baseline: +0.4% Memory: ✅ 68.184MB (SLO: <70.500MB -3.3%) vs baseline: +5.0% ✅ span-code-originTime: ✅ 19.875ms (SLO: <28.200ms 📉 -29.5%) vs baseline: +0.5% Memory: ✅ 68.120MB (SLO: <71.000MB -4.1%) vs baseline: +4.9% ✅ tracerTime: ✅ 19.661ms (SLO: <21.750ms -9.6%) vs baseline: +0.7% Memory: ✅ 68.164MB (SLO: <70.000MB -2.6%) vs baseline: +4.9% ✅ tracer-and-profilerTime: ✅ 21.759ms (SLO: <23.500ms -7.4%) vs baseline: -0.1% Memory: ✅ 69.206MB (SLO: <71.000MB -2.5%) vs baseline: +4.8% ✅ tracer-dont-create-db-spansTime: ✅ 19.652ms (SLO: <21.500ms -8.6%) vs baseline: +0.2% Memory: ✅ 68.243MB (SLO: <70.000MB -2.5%) vs baseline: +5.0% ✅ tracer-minimalTime: ✅ 16.831ms (SLO: <17.500ms -3.8%) vs baseline: +0.4% Memory: ✅ 67.755MB (SLO: <70.000MB -3.2%) vs baseline: +4.6% ✅ tracer-nativeTime: ✅ 19.495ms (SLO: <21.750ms 📉 -10.4%) vs baseline: -0.1% Memory: ✅ 68.184MB (SLO: <72.500MB -6.0%) vs baseline: +4.7% ✅ tracer-no-cachesTime: ✅ 17.616ms (SLO: <19.650ms 📉 -10.4%) vs baseline: -0.1% Memory: ✅ 68.164MB (SLO: <70.000MB -2.6%) vs baseline: +5.1% ✅ tracer-no-databasesTime: ✅ 19.168ms (SLO: <20.100ms -4.6%) vs baseline: +0.5% Memory: ✅ 67.771MB (SLO: <70.000MB -3.2%) vs baseline: +4.8% ✅ tracer-no-middlewareTime: ✅ 19.372ms (SLO: <21.500ms -9.9%) vs baseline: +0.7% Memory: ✅ 68.164MB (SLO: <70.000MB -2.6%) vs baseline: +4.8% ✅ tracer-no-templatesTime: ✅ 19.565ms (SLO: <22.000ms 📉 -11.1%) vs baseline: +1.1% Memory: ✅ 68.156MB (SLO: <70.500MB -3.3%) vs baseline: +4.8% 🟡 errortrackingdjangosimple - 6/6✅ errortracking-enabled-allTime: ✅ 16.363ms (SLO: <19.850ms 📉 -17.6%) vs baseline: ~same Memory: ✅ 69.835MB (SLO: <70.000MB 🟡 -0.2%) vs baseline: +4.8% ✅ errortracking-enabled-userTime: ✅ 16.379ms (SLO: <19.400ms 📉 -15.6%) vs baseline: +0.3% Memory: ✅ 69.796MB (SLO: <70.000MB 🟡 -0.3%) vs baseline: +4.8% ✅ tracer-enabledTime: ✅ 16.354ms (SLO: <19.450ms 📉 -15.9%) vs baseline: -0.1% Memory: ✅ 69.855MB (SLO: <70.000MB 🟡 -0.2%) vs baseline: +5.0% 🟡 errortrackingflasksqli - 6/6✅ errortracking-enabled-allTime: ✅ 2.068ms (SLO: <2.300ms 📉 -10.1%) vs baseline: -0.1% Memory: ✅ 55.758MB (SLO: <56.500MB 🟡 -1.3%) vs baseline: +4.9% ✅ errortracking-enabled-userTime: ✅ 2.074ms (SLO: <2.250ms -7.8%) vs baseline: ~same Memory: ✅ 55.758MB (SLO: <56.500MB 🟡 -1.3%) vs baseline: +5.0% ✅ tracer-enabledTime: ✅ 2.064ms (SLO: <2.300ms 📉 -10.3%) vs baseline: +0.1% Memory: ✅ 55.738MB (SLO: <56.500MB 🟡 -1.3%) vs baseline: +4.9% 🟡 flasksimple - 18/18✅ appsec-getTime: ✅ 3.371ms (SLO: <4.750ms 📉 -29.0%) vs baseline: -0.5% Memory: ✅ 55.511MB (SLO: <66.500MB 📉 -16.5%) vs baseline: +4.9% ✅ appsec-postTime: ✅ 2.860ms (SLO: <6.750ms 📉 -57.6%) vs baseline: ~same Memory: ✅ 55.862MB (SLO: <66.500MB 📉 -16.0%) vs baseline: +5.1% ✅ appsec-telemetryTime: ✅ 3.411ms (SLO: <4.750ms 📉 -28.2%) vs baseline: +0.9% Memory: ✅ 55.547MB (SLO: <66.500MB 📉 -16.5%) vs baseline: +5.0% ✅ debuggerTime: ✅ 1.873ms (SLO: <2.000ms -6.4%) vs baseline: +0.2% Memory: ✅ 47.919MB (SLO: <49.500MB -3.2%) vs baseline: +4.8% ✅ iast-getTime: ✅ 1.856ms (SLO: <2.000ms -7.2%) vs baseline: ~same Memory: ✅ 44.577MB (SLO: <49.000MB -9.0%) vs baseline: +4.7% ✅ profilerTime: ✅ 1.909ms (SLO: <2.100ms -9.1%) vs baseline: ~same Memory: ✅ 48.881MB (SLO: <50.000MB -2.2%) vs baseline: +4.9% ✅ resource-renamingTime: ✅ 3.354ms (SLO: <3.650ms -8.1%) vs baseline: ~same Memory: ✅ 55.470MB (SLO: <56.000MB 🟡 -0.9%) vs baseline: +4.7% ✅ tracerTime: ✅ 3.365ms (SLO: <3.650ms -7.8%) vs baseline: -0.2% Memory: ✅ 55.489MB (SLO: <56.500MB 🟡 -1.8%) vs baseline: +4.8% ✅ tracer-nativeTime: ✅ 3.372ms (SLO: <3.650ms -7.6%) vs baseline: ~same Memory: ✅ 55.510MB (SLO: <60.000MB -7.5%) vs baseline: +4.8% 🟡 flasksqli - 6/6✅ appsec-enabledTime: ✅ 2.061ms (SLO: <4.200ms 📉 -50.9%) vs baseline: ~same Memory: ✅ 55.797MB (SLO: <66.000MB 📉 -15.5%) vs baseline: +4.9% ✅ iast-enabledTime: ✅ 2.073ms (SLO: <2.800ms 📉 -26.0%) vs baseline: +0.2% Memory: ✅ 55.778MB (SLO: <62.500MB 📉 -10.8%) vs baseline: +4.7% ✅ tracer-enabledTime: ✅ 2.054ms (SLO: <2.250ms -8.7%) vs baseline: ~same Memory: ✅ 55.817MB (SLO: <56.500MB 🟡 -1.2%) vs baseline: +4.9% 🟡 httppropagationextract - 60/60✅ all_styles_all_headersTime: ✅ 81.117µs (SLO: <100.000µs 📉 -18.9%) vs baseline: -0.7% Memory: ✅ 34.859MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +4.9% ✅ b3_headersTime: ✅ 14.142µs (SLO: <20.000µs 📉 -29.3%) vs baseline: -0.1% Memory: ✅ 34.859MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +4.9% ✅ b3_single_headersTime: ✅ 13.234µs (SLO: <20.000µs 📉 -33.8%) vs baseline: -0.9% Memory: ✅ 34.819MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.7% ✅ datadog_tracecontext_tracestate_not_propagated_on_trace_id_no_matchTime: ✅ 64.013µs (SLO: <80.000µs 📉 -20.0%) vs baseline: +0.3% Memory: ✅ 34.839MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +5.1% ✅ datadog_tracecontext_tracestate_propagated_on_trace_id_matchTime: ✅ 66.248µs (SLO: <80.000µs 📉 -17.2%) vs baseline: ~same Memory: ✅ 34.878MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +5.0% ✅ empty_headersTime: ✅ 1.618µs (SLO: <10.000µs 📉 -83.8%) vs baseline: -0.3% Memory: ✅ 34.780MB (SLO: <35.500MB -2.0%) vs baseline: +4.7% ✅ full_t_id_datadog_headersTime: ✅ 22.465µs (SLO: <30.000µs 📉 -25.1%) vs baseline: ~same Memory: ✅ 34.819MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.7% ✅ invalid_priority_headerTime: ✅ 6.539µs (SLO: <10.000µs 📉 -34.6%) vs baseline: -0.3% Memory: ✅ 34.780MB (SLO: <35.500MB -2.0%) vs baseline: +4.7% ✅ invalid_span_id_headerTime: ✅ 6.560µs (SLO: <10.000µs 📉 -34.4%) vs baseline: +0.2% Memory: ✅ 34.780MB (SLO: <35.500MB -2.0%) vs baseline: +5.1% ✅ invalid_tags_headerTime: ✅ 6.533µs (SLO: <10.000µs 📉 -34.7%) vs baseline: ~same Memory: ✅ 34.878MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +5.0% ✅ invalid_trace_id_headerTime: ✅ 6.502µs (SLO: <10.000µs 📉 -35.0%) vs baseline: -0.5% Memory: ✅ 34.780MB (SLO: <35.500MB -2.0%) vs baseline: +4.6% ✅ large_header_no_matchesTime: ✅ 27.451µs (SLO: <30.000µs -8.5%) vs baseline: -0.6% Memory: ✅ 34.780MB (SLO: <35.500MB -2.0%) vs baseline: +4.6% ✅ large_valid_headers_allTime: ✅ 28.760µs (SLO: <40.000µs 📉 -28.1%) vs baseline: -0.8% Memory: ✅ 34.859MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +4.6% ✅ medium_header_no_matchesTime: ✅ 9.848µs (SLO: <20.000µs 📉 -50.8%) vs baseline: -0.8% Memory: ✅ 34.819MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.9% ✅ medium_valid_headers_allTime: ✅ 11.302µs (SLO: <20.000µs 📉 -43.5%) vs baseline: ~same Memory: ✅ 34.819MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.6% ✅ none_propagation_styleTime: ✅ 1.731µs (SLO: <10.000µs 📉 -82.7%) vs baseline: +0.5% Memory: ✅ 34.780MB (SLO: <35.500MB -2.0%) vs baseline: +4.4% ✅ tracecontext_headersTime: ✅ 34.849µs (SLO: <40.000µs 📉 -12.9%) vs baseline: +0.2% Memory: ✅ 34.819MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.9% ✅ valid_headers_allTime: ✅ 6.505µs (SLO: <10.000µs 📉 -34.9%) vs baseline: -0.5% Memory: ✅ 34.898MB (SLO: <35.500MB 🟡 -1.7%) vs baseline: +5.1% ✅ valid_headers_basicTime: ✅ 6.082µs (SLO: <10.000µs 📉 -39.2%) vs baseline: -0.6% Memory: ✅ 34.859MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +4.9% ✅ wsgi_empty_headersTime: ✅ 1.634µs (SLO: <10.000µs 📉 -83.7%) vs baseline: +0.4% Memory: ✅ 34.780MB (SLO: <35.500MB -2.0%) vs baseline: +4.6% ✅ wsgi_invalid_priority_headerTime: ✅ 6.598µs (SLO: <10.000µs 📉 -34.0%) vs baseline: +0.2% Memory: ✅ 34.859MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +4.9% ✅ wsgi_invalid_span_id_headerTime: ✅ 1.618µs (SLO: <10.000µs 📉 -83.8%) vs baseline: ~same Memory: ✅ 34.898MB (SLO: <35.500MB 🟡 -1.7%) vs baseline: +5.0% ✅ wsgi_invalid_tags_headerTime: ✅ 6.534µs (SLO: <10.000µs 📉 -34.7%) vs baseline: -0.6% Memory: ✅ 34.859MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +4.6% ✅ wsgi_invalid_trace_id_headerTime: ✅ 6.628µs (SLO: <10.000µs 📉 -33.7%) vs baseline: +1.5% Memory: ✅ 34.839MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.6% ✅ wsgi_large_header_no_matchesTime: ✅ 28.765µs (SLO: <40.000µs 📉 -28.1%) vs baseline: ~same Memory: ✅ 34.898MB (SLO: <35.500MB 🟡 -1.7%) vs baseline: +5.0% ✅ wsgi_large_valid_headers_allTime: ✅ 29.870µs (SLO: <40.000µs 📉 -25.3%) vs baseline: -0.1% Memory: ✅ 34.898MB (SLO: <35.500MB 🟡 -1.7%) vs baseline: +5.0% ✅ wsgi_medium_header_no_matchesTime: ✅ 10.197µs (SLO: <20.000µs 📉 -49.0%) vs baseline: -0.3% Memory: ✅ 34.878MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +4.6% ✅ wsgi_medium_valid_headers_allTime: ✅ 11.689µs (SLO: <20.000µs 📉 -41.6%) vs baseline: -0.5% Memory: ✅ 34.839MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.7% ✅ wsgi_valid_headers_allTime: ✅ 6.549µs (SLO: <10.000µs 📉 -34.5%) vs baseline: -0.6% Memory: ✅ 34.878MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +5.0% ✅ wsgi_valid_headers_basicTime: ✅ 6.115µs (SLO: <10.000µs 📉 -38.8%) vs baseline: -0.3% Memory: ✅ 34.819MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.4% 🟡 httppropagationinject - 16/16✅ ids_onlyTime: ✅ 21.940µs (SLO: <30.000µs 📉 -26.9%) vs baseline: +5.2% Memory: ✅ 34.819MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.9% ✅ with_allTime: ✅ 27.591µs (SLO: <40.000µs 📉 -31.0%) vs baseline: -0.3% Memory: ✅ 34.859MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +4.7% ✅ with_dd_originTime: ✅ 24.640µs (SLO: <30.000µs 📉 -17.9%) vs baseline: -0.2% Memory: ✅ 34.898MB (SLO: <35.500MB 🟡 -1.7%) vs baseline: +5.1% ✅ with_priority_and_originTime: ✅ 23.893µs (SLO: <40.000µs 📉 -40.3%) vs baseline: -0.2% Memory: ✅ 34.878MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +5.1% ✅ with_sampling_priorityTime: ✅ 20.740µs (SLO: <30.000µs 📉 -30.9%) vs baseline: -0.4% Memory: ✅ 34.898MB (SLO: <35.500MB 🟡 -1.7%) vs baseline: +5.0% ✅ with_tagsTime: ✅ 25.692µs (SLO: <40.000µs 📉 -35.8%) vs baseline: -0.9% Memory: ✅ 34.859MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +5.2% ✅ with_tags_invalidTime: ✅ 27.122µs (SLO: <40.000µs 📉 -32.2%) vs baseline: +0.1% Memory: ✅ 34.800MB (SLO: <35.500MB 🟡 -2.0%) vs baseline: +4.7% ✅ with_tags_max_sizeTime: ✅ 26.234µs (SLO: <40.000µs 📉 -34.4%) vs baseline: +0.3% Memory: ✅ 34.918MB (SLO: <35.500MB 🟡 -1.6%) vs baseline: +5.1% 🟡 otelspan - 22/22✅ add-eventTime: ✅ 40.391ms (SLO: <47.150ms 📉 -14.3%) vs baseline: +0.3% Memory: ✅ 39.522MB (SLO: <47.000MB 📉 -15.9%) vs baseline: +5.1% ✅ add-metricsTime: ✅ 259.957ms (SLO: <344.800ms 📉 -24.6%) vs baseline: -0.4% Memory: ✅ 43.736MB (SLO: <47.500MB -7.9%) vs baseline: +4.8% ✅ add-tagsTime: ✅ 315.854ms (SLO: <321.000ms 🟡 -1.6%) vs baseline: -0.1% Memory: ✅ 43.768MB (SLO: <47.500MB -7.9%) vs baseline: +5.2% ✅ get-contextTime: ✅ 80.337ms (SLO: <92.350ms 📉 -13.0%) vs baseline: ~same Memory: ✅ 39.820MB (SLO: <46.500MB 📉 -14.4%) vs baseline: +4.8% ✅ is-recordingTime: ✅ 37.989ms (SLO: <44.500ms 📉 -14.6%) vs baseline: -0.3% Memory: ✅ 39.533MB (SLO: <47.500MB 📉 -16.8%) vs baseline: +4.8% ✅ record-exceptionTime: ✅ 58.890ms (SLO: <67.650ms 📉 -12.9%) vs baseline: -0.3% Memory: ✅ 39.944MB (SLO: <47.000MB 📉 -15.0%) vs baseline: +5.0% ✅ set-statusTime: ✅ 44.294ms (SLO: <50.400ms 📉 -12.1%) vs baseline: ~same Memory: ✅ 39.509MB (SLO: <47.000MB 📉 -15.9%) vs baseline: +5.1% ✅ startTime: ✅ 38.149ms (SLO: <43.450ms 📉 -12.2%) vs baseline: +2.5% Memory: ✅ 39.417MB (SLO: <47.000MB 📉 -16.1%) vs baseline: +4.7% ✅ start-finishTime: ✅ 82.911ms (SLO: <88.000ms -5.8%) vs baseline: ~same Memory: ✅ 37.277MB (SLO: <46.500MB 📉 -19.8%) vs baseline: +4.7% ✅ start-finish-telemetryTime: ✅ 84.197ms (SLO: <89.000ms -5.4%) vs baseline: ~same Memory: ✅ 37.415MB (SLO: <46.500MB 📉 -19.5%) vs baseline: +5.4% ✅ update-nameTime: ✅ 38.800ms (SLO: <45.150ms 📉 -14.1%) vs baseline: +0.3% Memory: ✅ 39.509MB (SLO: <47.000MB 📉 -15.9%) vs baseline: +4.7% 🟡 ratelimiter - 12/12✅ defaultsTime: ✅ 2.362µs (SLO: <10.000µs 📉 -76.4%) vs baseline: -0.6% Memory: ✅ 35.075MB (SLO: <35.500MB 🟡 -1.2%) vs baseline: +4.6% ✅ high_rate_limitTime: ✅ 2.426µs (SLO: <10.000µs 📉 -75.7%) vs baseline: -0.1% Memory: ✅ 35.075MB (SLO: <35.500MB 🟡 -1.2%) vs baseline: +4.9% ✅ long_windowTime: ✅ 2.380µs (SLO: <10.000µs 📉 -76.2%) vs baseline: +0.7% Memory: ✅ 35.075MB (SLO: <35.500MB 🟡 -1.2%) vs baseline: +5.0% ✅ low_rate_limitTime: ✅ 2.358µs (SLO: <10.000µs 📉 -76.4%) vs baseline: +0.4% Memory: ✅ 35.154MB (SLO: <35.500MB 🟡 -1.0%) vs baseline: +5.1% ✅ no_rate_limitTime: ✅ 0.827µs (SLO: <10.000µs 📉 -91.7%) vs baseline: +1.1% Memory: ✅ 35.134MB (SLO: <35.500MB 🟡 -1.0%) vs baseline: +5.1% ✅ short_windowTime: ✅ 2.475µs (SLO: <10.000µs 📉 -75.2%) vs baseline: -0.8% Memory: ✅ 35.095MB (SLO: <35.500MB 🟡 -1.1%) vs baseline: +4.7% 🟡 recursivecomputation - 8/8✅ deepTime: ✅ 308.922ms (SLO: <320.950ms -3.7%) vs baseline: +0.3% Memory: ✅ 35.842MB (SLO: <36.500MB 🟡 -1.8%) vs baseline: +4.5% ✅ deep-profiledTime: ✅ 327.767ms (SLO: <359.150ms -8.7%) vs baseline: -0.5% Memory: ✅ 39.734MB (SLO: <40.500MB 🟡 -1.9%) vs baseline: +4.8% ✅ mediumTime: ✅ 6.990ms (SLO: <7.400ms -5.5%) vs baseline: +0.2% Memory: ✅ 34.760MB (SLO: <35.500MB -2.1%) vs baseline: +4.7% ✅ shallowTime: ✅ 0.948ms (SLO: <1.050ms -9.7%) vs baseline: +1.2% Memory: ✅ 34.721MB (SLO: <35.500MB -2.2%) vs baseline: +4.7% 🟡 samplingrules - 8/8✅ average_matchTime: ✅ 137.086µs (SLO: <290.000µs 📉 -52.7%) vs baseline: -0.6% Memory: ✅ 34.682MB (SLO: <35.500MB -2.3%) vs baseline: +4.5% ✅ high_matchTime: ✅ 174.129µs (SLO: <480.000µs 📉 -63.7%) vs baseline: +0.3% Memory: ✅ 34.839MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +5.0% ✅ low_matchTime: ✅ 98.640µs (SLO: <120.000µs 📉 -17.8%) vs baseline: -0.3% Memory: ✅ 603.474MB (SLO: <700.000MB 📉 -13.8%) vs baseline: +4.9% ✅ very_low_matchTime: ✅ 2.654ms (SLO: <8.500ms 📉 -68.8%) vs baseline: -0.1% Memory: ✅ 71.060MB (SLO: <75.000MB -5.3%) vs baseline: +4.9% 🟡 sethttpmeta - 32/32✅ all-disabledTime: ✅ 10.648µs (SLO: <20.000µs 📉 -46.8%) vs baseline: +0.9% Memory: ✅ 35.606MB (SLO: <36.000MB 🟡 -1.1%) vs baseline: +4.8% ✅ all-enabledTime: ✅ 41.087µs (SLO: <50.000µs 📉 -17.8%) vs baseline: +1.8% Memory: ✅ 35.330MB (SLO: <36.000MB 🟡 -1.9%) vs baseline: +4.0% ✅ collectipvariant_existsTime: ✅ 40.984µs (SLO: <50.000µs 📉 -18.0%) vs baseline: ~same Memory: ✅ 35.232MB (SLO: <36.000MB -2.1%) vs baseline: +3.3% ✅ no-collectipvariantTime: ✅ 40.112µs (SLO: <50.000µs 📉 -19.8%) vs baseline: -0.5% Memory: ✅ 35.370MB (SLO: <36.000MB 🟡 -1.8%) vs baseline: +4.0% ✅ no-useragentvariantTime: ✅ 39.085µs (SLO: <50.000µs 📉 -21.8%) vs baseline: +0.4% Memory: ✅ 35.409MB (SLO: <36.000MB 🟡 -1.6%) vs baseline: +4.6% ✅ obfuscation-no-queryTime: ✅ 40.812µs (SLO: <50.000µs 📉 -18.4%) vs baseline: +0.2% Memory: ✅ 35.232MB (SLO: <36.000MB -2.1%) vs baseline: +3.6% ✅ obfuscation-regular-case-explicit-queryTime: ✅ 76.253µs (SLO: <90.000µs 📉 -15.3%) vs baseline: +0.8% Memory: ✅ 35.625MB (SLO: <36.500MB -2.4%) vs baseline: +4.8% ✅ obfuscation-regular-case-implicit-queryTime: ✅ 76.667µs (SLO: <90.000µs 📉 -14.8%) vs baseline: +0.6% Memory: ✅ 35.606MB (SLO: <36.500MB -2.5%) vs baseline: +4.6% ✅ obfuscation-send-querystring-disabledTime: ✅ 154.561µs (SLO: <170.000µs -9.1%) vs baseline: +0.2% Memory: ✅ 35.625MB (SLO: <36.500MB -2.4%) vs baseline: +4.7% ✅ obfuscation-worst-case-explicit-queryTime: ✅ 148.824µs (SLO: <160.000µs -7.0%) vs baseline: ~same Memory: ✅ 35.665MB (SLO: <36.500MB -2.3%) vs baseline: +4.8% ✅ obfuscation-worst-case-implicit-queryTime: ✅ 155.435µs (SLO: <170.000µs -8.6%) vs baseline: +0.1% Memory: ✅ 35.743MB (SLO: <36.500MB -2.1%) vs baseline: +5.0% ✅ useragentvariant_exists_1Time: ✅ 39.644µs (SLO: <50.000µs 📉 -20.7%) vs baseline: -0.3% Memory: ✅ 35.291MB (SLO: <36.000MB 🟡 -2.0%) vs baseline: +3.9% ✅ useragentvariant_exists_2Time: ✅ 40.884µs (SLO: <50.000µs 📉 -18.2%) vs baseline: +0.3% Memory: ✅ 35.370MB (SLO: <36.000MB 🟡 -1.8%) vs baseline: +4.0% ✅ useragentvariant_exists_3Time: ✅ 40.246µs (SLO: <50.000µs 📉 -19.5%) vs baseline: -0.2% Memory: ✅ 35.429MB (SLO: <36.000MB 🟡 -1.6%) vs baseline: +4.2% ✅ useragentvariant_not_exists_1Time: ✅ 39.683µs (SLO: <50.000µs 📉 -20.6%) vs baseline: -0.2% Memory: ✅ 35.271MB (SLO: <36.000MB -2.0%) vs baseline: +3.8% ✅ useragentvariant_not_exists_2Time: ✅ 39.568µs (SLO: <50.000µs 📉 -20.9%) vs baseline: -0.1% Memory: ✅ 35.389MB (SLO: <36.000MB 🟡 -1.7%) vs baseline: +4.0% 🟡 span - 26/26✅ add-eventTime: ✅ 18.282ms (SLO: <22.500ms 📉 -18.7%) vs baseline: +0.3% Memory: ✅ 36.900MB (SLO: <53.000MB 📉 -30.4%) vs baseline: +5.0% ✅ add-metricsTime: ✅ 88.407ms (SLO: <93.500ms -5.4%) vs baseline: -0.5% Memory: ✅ 41.052MB (SLO: <53.000MB 📉 -22.5%) vs baseline: +4.7% ✅ add-tagsTime: ✅ 141.663ms (SLO: <155.000ms -8.6%) vs baseline: -0.7% Memory: ✅ 41.034MB (SLO: <53.000MB 📉 -22.6%) vs baseline: +4.7% ✅ get-contextTime: ✅ 17.046ms (SLO: <20.500ms 📉 -16.8%) vs baseline: +0.1% Memory: ✅ 36.743MB (SLO: <53.000MB 📉 -30.7%) vs baseline: +4.7% ✅ is-recordingTime: ✅ 17.332ms (SLO: <20.500ms 📉 -15.5%) vs baseline: +0.3% Memory: ✅ 36.762MB (SLO: <53.000MB 📉 -30.6%) vs baseline: +5.0% ✅ record-exceptionTime: ✅ 36.621ms (SLO: <40.000ms -8.4%) vs baseline: +0.4% Memory: ✅ 37.317MB (SLO: <53.000MB 📉 -29.6%) vs baseline: +4.9% ✅ set-statusTime: ✅ 18.662ms (SLO: <22.000ms 📉 -15.2%) vs baseline: -0.2% Memory: ✅ 36.683MB (SLO: <53.000MB 📉 -30.8%) vs baseline: +4.7% ✅ startTime: ✅ 17.338ms (SLO: <20.500ms 📉 -15.4%) vs baseline: +3.0% Memory: ✅ 36.703MB (SLO: <53.000MB 📉 -30.7%) vs baseline: +4.8% ✅ start-finishTime: ✅ 50.964ms (SLO: <52.500ms -2.9%) vs baseline: -0.5% Memory: ✅ 34.760MB (SLO: <35.500MB -2.1%) vs baseline: +4.7% ✅ start-finish-telemetryTime: ✅ 52.417ms (SLO: <54.500ms -3.8%) vs baseline: +0.3% Memory: ✅ 34.800MB (SLO: <35.500MB 🟡 -2.0%) vs baseline: +5.0% ✅ start-finish-traceid128Time: ✅ 54.209ms (SLO: <57.000ms -4.9%) vs baseline: +0.2% Memory: ✅ 34.760MB (SLO: <35.500MB -2.1%) vs baseline: +4.7% ✅ start-traceid128Time: ✅ 17.348ms (SLO: <22.500ms 📉 -22.9%) vs baseline: +1.1% Memory: ✅ 36.745MB (SLO: <53.000MB 📉 -30.7%) vs baseline: +4.9% ✅ update-nameTime: ✅ 17.225ms (SLO: <22.000ms 📉 -21.7%) vs baseline: -0.4% Memory: ✅ 36.902MB (SLO: <53.000MB 📉 -30.4%) vs baseline: +5.0% 🟡 tracer - 6/6✅ largeTime: ✅ 29.215ms (SLO: <32.950ms 📉 -11.3%) vs baseline: -0.3% Memory: ✅ 35.920MB (SLO: <36.500MB 🟡 -1.6%) vs baseline: +4.9% ✅ mediumTime: ✅ 2.891ms (SLO: <3.200ms -9.7%) vs baseline: -0.2% Memory: ✅ 34.721MB (SLO: <35.500MB -2.2%) vs baseline: +4.9% ✅ smallTime: ✅ 333.144µs (SLO: <370.000µs -10.0%) vs baseline: +2.0% Memory: ✅ 34.800MB (SLO: <35.500MB 🟡 -2.0%) vs baseline: +5.3%
|
ddtrace/internal/datadog/profiling/stack_v2/echion/echion/threads.h
Outdated
Show resolved
Hide resolved
ddtrace/internal/datadog/profiling/stack_v2/echion/echion/threads.h
Outdated
Show resolved
Hide resolved
ddtrace/internal/datadog/profiling/stack_v2/echion/echion/threads.h
Outdated
Show resolved
Hide resolved
ddtrace/internal/datadog/profiling/stack_v2/src/echion/frame.cc
Outdated
Show resolved
Hide resolved
ddtrace/internal/datadog/profiling/stack_v2/echion/echion/tasks.h
Outdated
Show resolved
Hide resolved
| #include <internal/pycore_frame.h> // for FRAME_CLEARED, FRAME_EXECUTING | ||
| #include <internal/pycore_interp_structs.h> // For PyInterpreterState | ||
| #include <internal/pycore_llist.h> // For llist_node structure | ||
| #include <internal/pycore_tstate.h> // For _PyThreadStateImpl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really want those // for ... comments? In my experience they tend to get outdated pretty quickly and they don't really add much as a lot of tools can report unused headers (which means the "why are we including this?" question isn't that relevant)
| #if PY_VERSION_HEX >= 0x030e0000 | ||
| // Python 3.14+: Get tasks from a single thread's linked-list | ||
| inline void | ||
| get_tasks_from_linked_list(uintptr_t head_addr, PyObject* loop, std::vector<TaskInfo::Ptr>& tasks) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a strong reason for using an output parameter over returning?
| // Copy head node struct from remote memory to local memory | ||
| struct llist_node head_node_local; | ||
| if (copy_type(reinterpret_cast<void*>(head_addr), head_node_local)) { | ||
| return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we return an error in this case?
| uintptr_t current_node_addr = head_addr; // Address of current node | ||
|
|
||
| // Copied from CPython's _remote_debugging_module.c: MAX_ITERATIONS | ||
| const size_t MAX_ITERATIONS = 2 << 15; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question Do you know why we're doing 2 << 15 and not 1 << 16? I've never seen that pattern anywhere else?
| if ((*maybe_task_info)->loop == loop) { | ||
| tasks.push_back(std::move(*maybe_task_info)); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For readability, I think adding an auto& task_info = *maybe_task_info could help.
| // ---------------------------------------------------------------------------- | ||
| inline Result<void> | ||
| ThreadInfo::sample(int64_t iid, PyThreadState* tstate, microsecond_t delta) | ||
| ThreadInfo::sample(int64_t iid, ThreadStateType* tstate_ptr, microsecond_t delta) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the renaming to tstate_ptr on purpose? I don't think we have _ptr suffixes in other places
| #if PY_VERSION_HEX >= 0x030e0000 | ||
| using ThreadStateCallback = std::function<void(_PyThreadStateImpl*, microsecond_t, ThreadInfo&)>; | ||
| #else | ||
| using ThreadStateCallback = std::function<void(PyThreadState*, microsecond_t, ThreadInfo&)>; | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
| # For Python 3.14+, we increase the sleep time to get all the samples | ||
| # as expected. It's likely because the CPython 3.14+ keeps track of | ||
| # the tasks in a linked list, and each node needs to be copied using | ||
| # a system call. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you by any chance run any performance checks for Python 3.14 on Tasks? I definitely believe this could be the explanation, but it's somewhat scary...
| # In Python 3.14+, generator frames intentionally break the frame chain by setting | ||
| # previous = NULL to prevent dangling pointers. This means we cannot unwind from | ||
| # generator frames back to their callers. See docs/python-3.14-generator-frame-limitation.md | ||
| # for details. | ||
| # | ||
| # Expected behavior: | ||
| # - Python < 3.14: my_function -> generator -> generator2 (full stack trace) | ||
| # - Python >= 3.14: generator -> generator2 (cannot unwind to my_function) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty bad, it sounds like a significant quality setback, right? Do we have any workarounds for it? (I guess not?)
Also, if I'm not mistaken, this means in practice we'll have the Generator Frames (and Frames for what it calls) as a separate sub-Flame Graph in the Flame Graph – wouldn't it make sense to completely ignore them instead?
I'm not sure what sounds worse... 😬
Description
This PR adds support for Python 3.14 in the profiler by updating it to handle CPython internal changes.
Key CPython changes addressed
_PyInterpreterFrameStructure ChangesInclude/internal/pycore_frame.htoInclude/internal/pycore_interpframe_structs.hPyObject *f_executableandPyObject *f_funcobjchanged to_PyStackReftype. Profilers like us now need to clear the LSB of these fields to get thePyObject*. See Use deferred reference counting in some_PyInterpreterFramefields python/cpython#123923 for detailsint stacktopfield removed, replaced with_PyStackRef *stackpointerpointer. See GH-120024: Use pointer for stack pointer python/cpython#121923 (GH-120024) for detailsPyObject *localsplus[1]changed to_PyStackRef localsplus[1]. See gh-117139: Convert the evaluation stack to stack refs python/cpython#118450 (gh-117139) for detailsFutureObj/TaskObjChangesawaited_by,is_task,awaited_by_is_setinFutureObj_HEADmacrostruct llist_node_task_nodefield for linked-list storageAsyncio Task Storage Changes
Prior to Python 3.14,
_scheduled_tasksWeakSet (exported from C extension)_eager_tasksset (exported from C extension)From Python 3.14,
asyncio.Tasksare stored in a linked-list (struct llist_node) per thread and per interpretertstate->asyncio_tasks_head(in_PyThreadStateImpl)interp->asyncio_tasks_head(for lingering tasks)TaskObjhas atask_nodefield withnextandprevpointers_scheduled_tasksWeakSet (now Python-only, not exported from C extension)_eager_taskssetImplementation Summary
Frame reading (
frame.h,frame.cc): Updated header includes to usepycore_interpframe_structs.hfor Python 3.14+. Implemented tagged pointer handling: clear LSB off_executableto recoverPyObject*(per gh-123923). Replacedstacktopfield access withstackpointerpointer arithmetic for stack depth calculation. UpdatedPyGen_yf()to use_PyStackRefandstackpointer[-1]instead oflocalsplus[stacktop-1]. Added handling forFRAME_OWNED_BY_INTERPRETERframe type (introduced in 3.14).Task structures (
cpython/tasks.h): Added Python 3.14+FutureObj_HEADmacro with new fields:awaited_by,is_task,awaited_by_is_set. Addedstruct llist_node task_nodefield toTaskObjfor linked-list storage. UpdatedPyGen_yf()implementation to handle_PyStackRefandstackpointerinstead ofstacktop.Asyncio discovery (
tasks.h,threads.h): Implementedget_tasks_from_linked_list()to safely iterate over circular linked-lists with iteration limits (MAX_ITERATIONS = 2 << 15). Addedget_tasks_from_thread_linked_list()to read tasks from_PyThreadStateImpl.asyncio_tasks_head(per-thread active tasks). Addedget_tasks_from_interpreter_linked_list()to read lingering tasks fromPyInterpreterState.asyncio_tasks_head(per-interpreter). Updatedget_all_tasks()to handle both linked-list (nativeasyncio.Taskinstances) and WeakSet (third-party tasks). ChangedThreadStateTypetypedef to_PyThreadStateImpl*for Python 3.14+ to accessasyncio_tasks_headdirectly. Updatedfor_each_thread()to copy_PyThreadStateImplinstead ofPyThreadStatefor 3.14+.Python integration (
_asyncio.py): Added compatibility handling forBaseDefaultEventLoopPolicy→_BaseDefaultEventLoopPolicyrename in 3.14. Updated_scheduled_tasksaccess to handle Python-only WeakSet (no longer exported from C extension in 3.14+).Testing
All existing tests pass except for these which needed some modifications, see comments in these files
Risks
Additional Notes