A simplified version of simpleperf report functionality extracted from Android NDK r29. This project focuses on simpleperf's performance reporting and visualization capabilities, removing unnecessary components and adding two key features to support integration with other web applications.
This project is based on the simpleperf tool from Android NDK r29, but only retains functionality related to performance reporting. The main goal is to provide a lightweight simpleperf HTML report generator that supports:
- Normalized data display: Convert event counts to a more readable format (kilo events/s)
- URL parameter navigation: Support direct navigation to specified processes, threads, and functions via URL parameters
This enables other web applications to easily integrate simpleperf's flamegraph visualization capabilities.
Enable normalization via the URL parameter ?norm to convert event counts to kilo events/s (thousand events per second) format, making it easier to compare performance data across different durations.
Normalization Duration Calculation:
The duration is parsed from the --duration parameter in the record command line. This provides accurate wall-clock time for calculating kilo events/s values.
Normalization Formula:
kiloEventsPerSecond = (eventCount / 1000.0) / duration
result = Math.round(kiloEventsPerSecond).toLocaleString()
Display Changes:
- Event type names are suffixed with
' (kilo events/s)'when normalization is enabled - All event counts throughout the UI (charts, tables, flamegraphs) are displayed in kilo events/s
- The normalization option is available in the Sample Table weight selector dropdown
Example:
report.html?norm
Support direct navigation to specific processes, threads, and functions via URL parameters, facilitating integration with other web applications.
Supported Parameters:
pid: Process ID (optional, can be used alone or with tid)tid: Thread ID (optional, can be used alone or with pid)event: Event name (optional, specifies which event type to analyze in multi-event profiling)function: Function name (optional, supports partial matching)library: Library name (optional, supports partial matching, used to filter function searches)
Navigation Behavior:
-
Process-Only Navigation:
- If only
pidis specified (notidand nofunction): Creates a newProcessFlameGraphTabshowing all threads in the specified process - Threads are sorted by event count (descending) within each event type
- Supports event filtering via
eventparameter - Functions in flamegraphs are clickable for detailed analysis
- If only
-
Thread Lookup (
findThreadByPidTid):- Searches through all event types and processes
- If
pidis specified, filters processes by PID - If
tidis specified, filters threads by TID - If
eventis specified, filters events by name using bidirectional substring matching - All parameters are optional - you can specify any combination
- Returns the first matching thread with associated event info and process info
-
Function Selection:
- If
functionparameter is provided (findFunctionByNameInThread):- Performs bidirectional substring matching: function name includes parameter OR parameter includes function name
- If
libraryparameter is provided, filters functions to those in matching libraries - Searches through all libraries and functions in the thread
- If not found, falls back to showing the hottest function in that thread
- If
functionparameter is not provided (findHotFunctionInThread):- Finds the function with the highest subtree event count (
func.c[2]) - Subtree event count includes the function itself plus all its callees
- This ensures the most significant performance hotspot is displayed
- Finds the function with the highest subtree event count (
- If
-
Function Display:
- Uses
FunctionTab.showFunction()static method to display function details - Creates a new "Function" tab if it doesn't exist
- Shows callgraph, reverse callgraph, annotated source code, and disassembly (if available)
- Navigation happens asynchronously during page load (at 60% progress)
- Uses
Function Data Structure: Each function object contains:
func.c[0]: Sample count (number of samples)func.c[1]: Self event count (events in this function only)func.c[2]: Subtree event count (events in this function + all callees)
Examples:
# Navigate to process 1234, showing all threads in ProcessFlameGraphTab
report.html?pid=1234
# Navigate to process 1234 with event filtering
report.html?pid=1234&event=instructions
# Navigate to process 1234, thread 5678, showing the hottest function
report.html?pid=1234&tid=5678
# Navigate to a specific function (partial name matching)
report.html?pid=1234&tid=5678&function=main
# Navigate to a specific function within a specific library
report.html?pid=1234&tid=5678&function=processData&library=mylib
# Navigate using only tid (searches all processes)
report.html?tid=5678
# Navigate to specific event type (useful in multi-event profiling)
report.html?pid=1234&tid=5678&event=instructions
# Combine event and function navigation
report.html?pid=1234&tid=5678&event=cycles&function=processData
# Event name partial matching (matches 'instructions', 'branch-instructions', etc.)
report.html?pid=1234&tid=5678&event=instr
# Library name partial matching
report.html?pid=1234&tid=5678&function=render&library=core
# Combine normalization and URL navigation with specific event
report.html?norm&pid=1234&tid=5678&event=instructions&function=processData
Chart Statistics Navigation:
- Process and Thread rows in tables have explicit "Go" buttons for navigation
- Clicking the "Go" button navigates to the corresponding detailed view
- Process view creates a new
ProcessFlameGraphTabshowing all threads in the process - Thread view creates a new
FunctionTabshowing the hottest function in that thread
Sample Table Navigation:
- All function rows in the sample table are clickable
- Clicking opens the function detail view with callgraphs and source code
Flamegraph Integration:
- Functions in all flamegraphs are clickable for detailed analysis
- ProcessFlameGraphTab functions also support navigation to FunctionTab
This project is based on simpleperf from Android Open Source Project (AOSP), licensed under Apache License 2.0.