tezvyn:

How would you use Perfetto and Trace.beginSection to find a non-obvious bottleneck?

Curated by the Tezvyn teamSource: perfetto.devadvanced
How would you use Perfetto and Trace.beginSection to find a non-obvious bottleneck?

Tests correlation beyond CPU sampling. Covers coarse Trace.beginSection to limit 1-10us overhead, recording app ATrace with CPU/scheduling tracks, and correlating slices against scheduler latency. Red flag: omitting overhead or ignoring Perfetto SQL queries.

WHAT THIS TESTS: This tests whether you can debug elusive performance issues that hide inside standard sampling profilers by combining custom app instrumentation with system-wide tracing. It checks knowledge of ATrace overhead characteristics, Perfetto configuration, and the ability to correlate app-level slices with kernel and system server behavior.

A GOOD ANSWER COVERS: First, strategic instrumentation. You bracket suspect code regions with Trace.beginSection and Trace.endSection, but you keep the granularity intentionally coarse. The canonical overhead is 1-10 microseconds per event due to stringification, a JNI call, and a user-space to kernel-space roundtrip to write into trace_marker. Instrumenting a tight loop would destroy the very signal you are trying to measure. Second, trace recording configuration. You enable app ATrace events for your specific package via Perfetto TraceConfig, targeting ATRACE_TAG_APP, and you simultaneously enable system tracks such as CPU frequency, scheduling, and binder transactions. This gives you a unified timeline that the Android Studio CPU Profiler cannot provide. Third, visual analysis. In the Perfetto UI you look for slices that are unexpectedly long, scheduling gaps where your thread is runnable but not running, or binder IPC blocking the main thread. Fourth, quantitative analysis. You use PerfettoSQL against the slice table to sum durations, group by thread, or compute percentiles across thousands of events, turning a visual hunch into hard numbers.

COMMON WRONG ANSWERS: A major red flag is proposing Trace.beginSection inside a tight loop or on every frame without mentioning the 1-10us overhead. Another is treating Perfetto as merely a prettier Systrace and ignoring the SQL layer or system-level tracks like CPU scheduling. Some candidates incorrectly suggest migrating to the new Tracing SDK on Android; the current official advice is to continue using the existing ATrace API. Finally, failing to mention endSection or discussing trace events without explaining how to balance granularity is a signal of shallow production experience.

LIKELY FOLLOW-UPS: How do you avoid observer effect when the trace itself adds latency? When would you use Trace.setCounter versus slices? How would you automate regression detection by querying slice durations across a fleet of traces? What is the difference between Perfetto and the Android Studio CPU Profiler for app instrumentation?

ONE CONCRETE EXAMPLE: Suppose RecyclerView scrolling stutters but the CPU profiler shows bind() taking only 2ms. You instrument bind(), image decode, and database query phases. After recording a ten-second trace with scheduling and binder tracks enabled, you discover the bind slice is fast, but the main thread sits runnable for 8ms immediately after while waiting on a binder IPC to the media server for image resizing. The fix is to move the resize to a background thread and cache the result, which eliminates the scheduling gap.

Source: perfetto.dev

Read the original → perfetto.dev

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.