Profiling the engine - flutter-tizen/flutter-tizen GitHub Wiki
Note: You need a rooted device (such as a Raspberry Pi) to use perf. You can't use emulators for profiling purposes because Dart doesn't support x86 AOT.
-
Download the kernel source code for your target device (e.g.
platform/kernel/linux-rpi
for Raspberry Pi 4). -
Locate the perf tool (
tools/perf
) in the kernel source code. We will cross build it via Docker ARM emulation. You can alternatively use GBS if you're familiar with it. -
Install Docker and QEMU packages on your host machine by referring to Install Docker Engine on Ubuntu and Running and Building ARM Docker Containers on x86.
-
Run a Docker container of your device's architecture. For example, if your device is an arm64 Raspberry Pi, run
docker run --rm -ti --platform linux/arm64 -v [path_to_repo]:/linux-rpi arm64v8/debian:buster bash
-
Build perf by running the following commands.
apt update apt install make gcc bison flex apt install libelf-dev libdw-dev systemtap-sdt-dev libunwind-dev \ libssl-dev python3 libiberty-dev libzstd-dev libcap-dev cd /linux-rpi/tools/perf make clean make
-
Once the build is done, copy the output executable (
perf
) to your device.sdb root on sdb push perf /home/owner/perf
-
Build your app in release mode with unstripped engine and embedder artifacts (by referring to Debugging the engine and embedder) and install to your device.
-
Open the sdb shell and type the following commands as root. (Replace
ELM_PROFILE
with your device's profile.)echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor export ELM_ENGINE=wayland_egl export ELM_DISPLAY=wl export HOME=/opt/usr/home/owner export ELM_PROFILE=common export XDG_RUNTIME_DIR=/run/user/5001 export DBUS_SESSION_BUS_ADDRESS="kernel:path=/sys/fs/kdbus/5001-user/bus;unix:path=/run/user/5001/bus"
-
Launch the app under perf. For example, if the app is a native app and its app ID is
io.flutter.demo.gallery
, runcd /home/owner AUL_APPID=io.flutter.demo.gallery ./perf record -v -F 5000 -g /opt/usr/globalapps/io.flutter.demo.gallery/bin/runner
Note: In case of a .NET application, replace
/opt/usr/.../runner
withdotnet-launcher --standalone /opt/usr/.../Runner.dll
. -
Once the app appears on the device screen, stop tracing by pressing
Ctrl
+C
. -
Process the raw sampling data (
perf.data
)../perf script > perf.script
-
Copy the file to your host machine.
sdb pull /home/owner/perf.script
The recorded perf data can be opened by various tools available online. Among them, the following two are recommended.
-
Drag and drop the
perf.script
file into the Firefox Profiler web UI. -
Clone the repository and run the following commands to convert
perf.script
into a.svg
file which can be opened by your browser.cat perf.script | ./stackcollapse-perf.pl > out.perf-folded cat out.perf-folded | ./flamegraph.pl > perf-kernel.svg
Caution: This method is outdated as of Flutter 2.5. Native symbols will not be resolved correctly even if you apply the following or any other methods suggested in https://github.com/flutter-tizen/engine/issues/95.
You can skip steps 1-2 and 6-7 if you don't need native stack traces but only want to trace events from the Dart code (framework).
-
Build the engine from source in profile mode. Before running the build, make sure to enable the
enable_profiling
flag by applying this patch. -
Once the build is done, find unstripped build artifacts (
so.unstripped
) from the output directory, and copy them to flutter-tizen's cached artifacts directory (flutter-tizen/flutter/bin/cache/artifacts/engine
). -
Build and run your app in profile mode.
flutter-tizen run --profile
-
Open DevTools and go to the Performance tab.
-
Let your app draw some frames and click one of the colored bars displayed in the FPS chart.
-
Click CPU Flame Chart in the below CPU Profile view. In the top right of the view, click the Filter icon () and make sure Hide Native code is unchecked.
-
Check if native symbols are displayed correctly in the CPU Flame Chart.
-
You can also use the CPU Profiler tab if you want to profile the app only for a specific duration. See Flutter Docs: CPU Profiler view for details.