| Title: | Text-Based Summaries for 'profvis' Profiling Data |
|---|---|
| Description: | Provides text-based summaries and analysis tools for 'profvis' profiling output. Designed for terminal workflows and artificial intelligence (AI) agent consumption, offering views including hotspot analysis, call trees, source context, caller/callee relationships, and memory allocation breakdowns. |
| Authors: | Emil Hvitfeldt [aut, cre], Posit Software, PBC [cph, fnd] (ROR: <https://ror.org/03wc8by49>) |
| Maintainer: | Emil Hvitfeldt <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0.9000 |
| Built: | 2026-05-22 18:52:05 UTC |
| Source: | https://github.com/r-lib/debrief |
Shows time distribution across different call stack depths. Useful for understanding how deeply nested the hot code paths are.
pv_call_depth(x)pv_call_depth(x)
x |
A profvis object. |
A data frame with columns:
depth: Call stack depth (1 = top level)
samples: Number of profiling samples at this depth
time_ms: Time in milliseconds
pct: Percentage of total time
top_funcs: Most common functions at this depth
p <- pv_example() pv_call_depth(p)p <- pv_example() pv_call_depth(p)
Shows call count, total time, self time, and time per call for each function. This is especially useful for identifying functions that are called many times (where per-call optimization or reducing call count would help).
pv_call_stats(x, n = NULL)pv_call_stats(x, n = NULL)
x |
A profvis object. |
n |
Maximum number of functions to return. If |
A data frame with columns:
label: Function name
calls: Estimated number of calls (based on stack appearances)
total_ms: Total time on call stack
self_ms: Time at top of stack (self time)
child_ms: Time in callees
ms_per_call: Average milliseconds per call
pct: Percentage of total profile time
p <- pv_example() pv_call_stats(p)p <- pv_example() pv_call_stats(p)
Returns the functions that a specified function calls, based on profiling data. Shows what the target function invokes.
pv_callees(x, func)pv_callees(x, func)
x |
A profvis object. |
func |
The function name to analyze. |
A data frame with columns:
label: Callee function name
samples: Number of times this callee appeared
pct: Percentage of calls to this callee
p <- pv_example() pv_callees(p, "outer")p <- pv_example() pv_callees(p, "outer")
Returns the functions that call a specified function, based on profiling data. Shows who invokes the target function.
pv_callers(x, func)pv_callers(x, func)
x |
A profvis object. |
func |
The function name to analyze. |
A data frame with columns:
label: Caller function name
samples: Number of times this caller appeared
pct: Percentage of calls from this caller
p <- pv_example() pv_callers(p, "inner")p <- pv_example() pv_callers(p, "inner")
Compares two profiling runs to show what changed. Useful for measuring the impact of optimizations.
pv_compare(before, after, n = 20)pv_compare(before, after, n = 20)
before |
A profvis object (before optimization). |
after |
A profvis object (after optimization). |
n |
Number of top functions to compare. |
A list with:
summary: Overall comparison summary
by_function: Function-by-function comparison
improved: Functions that got faster
regressed: Functions that got slower
p1 <- pv_example() p2 <- pv_example() pv_compare(p1, p2)p1 <- pv_example() p2 <- pv_example() pv_compare(p1, p2)
Compares multiple profiling runs to identify the fastest. Useful for comparing different optimization approaches.
pv_compare_many(...)pv_compare_many(...)
... |
Named profvis objects to compare, or a single named list of profvis objects. |
A data frame with columns:
name: Profile name
time_ms: Total time in milliseconds
samples: Number of samples
vs_fastest: How much slower than the fastest (e.g., "1.5x")
rank: Rank from fastest (1) to slowest
p1 <- pv_example() p2 <- pv_example("gc") p3 <- pv_example("recursive") pv_compare_many(baseline = p1, gc_heavy = p2, recursive = p3) # Or pass a named list profiles <- list(baseline = p1, gc_heavy = p2) pv_compare_many(profiles)p1 <- pv_example() p2 <- pv_example("gc") p3 <- pv_example("recursive") pv_compare_many(baseline = p1, gc_heavy = p2, recursive = p3) # Or pass a named list profiles <- list(baseline = p1, gc_heavy = p2) pv_compare_many(profiles)
Returns all profiling analysis in a single list for programmatic access. This is the primary function for AI agents and scripts that need comprehensive profiling data without printed output.
pv_debrief(x, n = 10)pv_debrief(x, n = 10)
x |
A profvis object from |
n |
Maximum number of items to include in each category (default 10). |
A list containing:
total_time_ms: Total profiling time in milliseconds
total_samples: Number of profiling samples
interval_ms: Sampling interval in milliseconds
has_source: Whether source references are available
self_time: Data frame of functions by self-time
total_time: Data frame of functions by total time
hot_lines: Data frame of hot source lines (or NULL if no source refs)
hot_paths: Data frame of hot call paths
suggestions: Data frame of optimization suggestions
gc_pressure: Data frame of GC pressure analysis
memory: Data frame of memory allocation by function
memory_lines: Data frame of memory allocation by line (or NULL)
p <- pv_example() d <- pv_debrief(p) names(d) d$self_timep <- pv_example() d <- pv_debrief(p) names(d) d$self_time
Creates an example profvis object for use in examples and testing. This avoids the need to run actual profiling code in examples.
pv_example(type = c("default", "no_source", "recursive", "gc"))pv_example(type = c("default", "no_source", "recursive", "gc"))
type |
Type of example data to create:
|
A profvis object that can be used with all debrief functions.
# Get default example data p <- pv_example() pv_self_time(p) # Get example with recursive calls p_recursive <- pv_example("recursive") pv_recursive(p_recursive)# Get default example data p <- pv_example() pv_self_time(p) # Get example with recursive calls p_recursive <- pv_example("recursive") pv_recursive(p_recursive)
Aggregates profiling time by source file. Requires source references
(use devtools::load_all() for best results).
pv_file_summary(x)pv_file_summary(x)
x |
A profvis object. |
A data frame with columns:
filename: Source file path
samples: Number of profiling samples
time_ms: Time in milliseconds
pct: Percentage of total time
p <- pv_example() pv_file_summary(p)p <- pv_example() pv_file_summary(p)
Generates an ASCII representation of a flame graph showing the hierarchical breakdown of time spent in the call tree.
pv_flame(x, width = 70, min_pct = 2, max_depth = 15)pv_flame(x, width = 70, min_pct = 2, max_depth = 15)
x |
A profvis object. |
width |
Width of the flame graph in characters. |
min_pct |
Minimum percentage to show (filters small slices). |
max_depth |
Maximum depth to display. |
Invisibly returns a debrief_flame object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_flame(p)p <- pv_example() pv_flame(p)
Shows a simplified, condensed view of the flame graph focusing on the hottest paths.
pv_flame_condense(x, n = 10, width = 50)pv_flame_condense(x, n = 10, width = 50)
x |
A profvis object. |
n |
Number of hot paths to show. |
width |
Width of bars. |
Invisibly returns a debrief_flame_condense object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_flame_condense(p)p <- pv_example() pv_flame_condense(p)
Provides a comprehensive analysis of a single function including time breakdown, callers, callees, and source context if available.
pv_focus(x, func, context = 5)pv_focus(x, func, context = 5)
x |
A profvis object. |
func |
The function name to analyze. |
context |
Number of source lines to show around hotspots. |
Invisibly returns a debrief_focus object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_focus(p, "inner")p <- pv_example() pv_focus(p, "inner")
Analyzes the profile to detect excessive garbage collection, which is a universal indicator of memory allocation issues in R code.
pv_gc_pressure(x, threshold = 10)pv_gc_pressure(x, threshold = 10)
x |
A profvis object. |
threshold |
Minimum GC percentage to report (default 10). Set lower to detect smaller GC overhead. |
GC pressure above 10% typically indicates the code is allocating and discarding memory faster than necessary. Common causes include:
Growing vectors with c(x, new) instead of pre-allocation
Building data frames row-by-row with rbind()
Creating unnecessary copies of large objects
String concatenation in loops
A data frame with columns:
severity: "high" (>25%), "medium" (>15%), or "low" (>threshold%)
pct: Percentage of total time spent in GC
time_ms: Time spent in garbage collection
issue: Short description of the problem
cause: What typically causes this issue
actions: Comma-separated list of things to look for
Returns an empty data frame (0 rows) if GC is below the threshold.
p <- pv_example("gc") pv_gc_pressure(p) # More sensitive detection pv_gc_pressure(p, threshold = 5) # No GC pressure in default example p2 <- pv_example() pv_gc_pressure(p2)p <- pv_example("gc") pv_gc_pressure(p) # More sensitive detection pv_gc_pressure(p, threshold = 5) # No GC pressure in default example p2 <- pv_example() pv_gc_pressure(p2)
Prints a summary of all available functions in the debrief package, organized by category. Useful for discovering the API.
pv_help(category = NULL)pv_help(category = NULL)
category |
Optional category to filter by. If |
Invisibly returns a debrief_help object. Use
capture.output() to capture the formatted text output.
pv_help() pv_help("time") pv_help("hotspots")pv_help() pv_help("time") pv_help("hotspots")
Returns the source lines where the most CPU time is spent. Requires source
references (use devtools::load_all() for best results).
pv_hot_lines(x, n = NULL, min_pct = 0, min_time_ms = 0)pv_hot_lines(x, n = NULL, min_pct = 0, min_time_ms = 0)
x |
A profvis object. |
n |
Maximum number of lines to return. If |
min_pct |
Minimum percentage of total time to include (default 0). |
min_time_ms |
Minimum time in milliseconds to include (default 0). |
A data frame with columns:
location: File path and line number (e.g., "R/foo.R:42")
label: Function name at this location
filename: Source file path
linenum: Line number
samples: Number of profiling samples
time_ms: Time in milliseconds
pct: Percentage of total time
p <- pv_example() pv_hot_lines(p) # Only lines with >= 10% of time pv_hot_lines(p, min_pct = 10)p <- pv_example() pv_hot_lines(p) # Only lines with >= 10% of time pv_hot_lines(p, min_pct = 10)
Returns the most common complete call stacks. This shows which execution paths through the code consume the most time.
pv_hot_paths(x, n = NULL, include_source = TRUE)pv_hot_paths(x, n = NULL, include_source = TRUE)
x |
A profvis object. |
n |
Maximum number of paths to return. If |
include_source |
If |
A data frame with columns:
stack: The call path (functions separated by arrows)
samples: Number of profiling samples with this exact path
time_ms: Time in milliseconds
pct: Percentage of total time
p <- pv_example() pv_hot_paths(p)p <- pv_example() pv_hot_paths(p)
Returns memory allocation aggregated by function name.
pv_memory(x, n = NULL)pv_memory(x, n = NULL)
x |
A profvis object. |
n |
Maximum number of functions to return. If |
A data frame with columns:
label: Function name
mem_mb: Memory allocated in megabytes
p <- pv_example() pv_memory(p)p <- pv_example() pv_memory(p)
Returns memory allocation aggregated by source location. Requires source
references (use devtools::load_all() for best results).
pv_memory_lines(x, n = NULL)pv_memory_lines(x, n = NULL)
x |
A profvis object. |
n |
Maximum number of lines to return. If |
A data frame with columns:
location: File path and line number
label: Function name at this location
filename: Source file path
linenum: Line number
mem_mb: Memory allocated in megabytes
p <- pv_example() pv_memory_lines(p)p <- pv_example() pv_memory_lines(p)
Print call depth breakdown
pv_print_call_depth(x)pv_print_call_depth(x)
x |
A profvis object. |
Invisibly returns a debrief_call_depth object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_print_call_depth(p)p <- pv_example() pv_print_call_depth(p)
Print call statistics
pv_print_call_stats(x, n = 20)pv_print_call_stats(x, n = 20)
x |
A profvis object. |
n |
Number of functions to show. |
Invisibly returns a debrief_call_stats object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_print_call_stats(p)p <- pv_example() pv_print_call_stats(p)
Shows both callers (who calls this function) and callees (what this function calls) in a single view.
pv_print_callers_callees(x, func, n = 10)pv_print_callers_callees(x, func, n = 10)
x |
A profvis object. |
func |
The function name to analyze. |
n |
Maximum number of callers/callees to show. |
Invisibly returns a debrief_callers_callees object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_print_callers_callees(p, "inner")p <- pv_example() pv_print_callers_callees(p, "inner")
Print profile comparison
pv_print_compare(before, after, n = 15)pv_print_compare(before, after, n = 15)
before |
A profvis object (before optimization). |
after |
A profvis object (after optimization). |
n |
Number of functions to show in detailed comparison. |
Invisibly returns a debrief_compare object. Use
capture.output() to capture the formatted text output.
p1 <- pv_example() p2 <- pv_example() pv_print_compare(p1, p2)p1 <- pv_example() p2 <- pv_example() pv_print_compare(p1, p2)
Print comparison of multiple profiles
pv_print_compare_many(...)pv_print_compare_many(...)
... |
Named profvis objects to compare, or a single named list. |
Invisibly returns a debrief_compare_many object. Use
capture.output() to capture the formatted text output.
p1 <- pv_example() p2 <- pv_example("gc") pv_print_compare_many(baseline = p1, gc_heavy = p2)p1 <- pv_example() p2 <- pv_example("gc") pv_print_compare_many(baseline = p1, gc_heavy = p2)
Prints a comprehensive text summary of profiling data suitable for terminal output or AI agent consumption.
pv_print_debrief(x, n_functions = 10, n_lines = 10, n_paths = 5, n_memory = 5)pv_print_debrief(x, n_functions = 10, n_lines = 10, n_paths = 5, n_memory = 5)
x |
A profvis object from |
n_functions |
Number of top functions to show (default 10). |
n_lines |
Number of hot source lines to show (default 10). |
n_paths |
Number of hot paths to show (default 5). |
n_memory |
Number of memory hotspots to show (default 5). |
Invisibly returns a debrief_debrief object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_print_debrief(p)p <- pv_example() pv_print_debrief(p)
Print file summary
pv_print_file_summary(x)pv_print_file_summary(x)
x |
A profvis object. |
Invisibly returns a debrief_file_summary object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_print_file_summary(p)p <- pv_example() pv_print_file_summary(p)
Print GC pressure analysis
pv_print_gc_pressure(x, threshold = 10)pv_print_gc_pressure(x, threshold = 10)
x |
A profvis object. |
threshold |
Minimum GC percentage to report (default 10). |
Invisibly returns a debrief_gc_pressure object. Use
capture.output() to capture the formatted text output.
p <- pv_example("gc") pv_print_gc_pressure(p)p <- pv_example("gc") pv_print_gc_pressure(p)
Prints the hot source lines along with surrounding code context.
pv_print_hot_lines(x, n = 5, context = 3)pv_print_hot_lines(x, n = 5, context = 3)
x |
A profvis object. |
n |
Number of hot lines to show. |
context |
Number of lines to show before and after each hotspot. |
Invisibly returns a debrief_hot_lines object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_print_hot_lines(p, n = 5, context = 3)p <- pv_example() pv_print_hot_lines(p, n = 5, context = 3)
Print hot paths in readable format
pv_print_hot_paths(x, n = 10, include_source = TRUE)pv_print_hot_paths(x, n = 10, include_source = TRUE)
x |
A profvis object. |
n |
Number of paths to show. |
include_source |
Include source references in output. |
Invisibly returns a debrief_hot_paths object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_print_hot_paths(p, n = 3)p <- pv_example() pv_print_hot_paths(p, n = 3)
Print memory allocation summary
pv_print_memory(x, n = 10, by = c("function", "line"))pv_print_memory(x, n = 10, by = c("function", "line"))
x |
A profvis object. |
n |
Number of top allocators to show. |
by |
Either "function" or "line". |
Invisibly returns a debrief_memory object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_print_memory(p, by = "function") pv_print_memory(p, by = "line")p <- pv_example() pv_print_memory(p, by = "function") pv_print_memory(p, by = "line")
Print recursive functions analysis
pv_print_recursive(x)pv_print_recursive(x)
x |
A profvis object. |
Invisibly returns a debrief_recursive object. Use
capture.output() to capture the formatted text output.
p <- pv_example("recursive") pv_print_recursive(p)p <- pv_example("recursive") pv_print_recursive(p)
Print optimization suggestions
pv_print_suggestions(x)pv_print_suggestions(x)
x |
A profvis object. |
Invisibly returns a debrief_suggestions object. Use
capture.output() to capture the formatted text output.
p <- pv_example("gc") pv_print_suggestions(p)p <- pv_example("gc") pv_print_suggestions(p)
Identifies functions that call themselves (directly recursive) or appear multiple times in the same call stack. Recursive functions in hot paths are often optimization targets.
pv_recursive(x)pv_recursive(x)
x |
A profvis object. |
A data frame with columns:
label: Function name
max_depth: Maximum recursion depth observed
avg_depth: Average recursion depth when recursive
recursive_samples: Number of samples where function appears multiple times
total_samples: Total samples where function appears
pct_recursive: Percentage of appearances that are recursive
total_ms: Total time on call stack
pct_time: Percentage of total profile time
p <- pv_example("recursive") pv_recursive(p)p <- pv_example("recursive") pv_recursive(p)
Returns the time spent directly in each function (at the top of the call stack). This shows where CPU cycles are actually being consumed.
pv_self_time(x, n = NULL, min_pct = 0, min_time_ms = 0)pv_self_time(x, n = NULL, min_pct = 0, min_time_ms = 0)
x |
A profvis object. |
n |
Maximum number of functions to return. If |
min_pct |
Minimum percentage of total time to include (default 0). |
min_time_ms |
Minimum time in milliseconds to include (default 0). |
A data frame with columns:
label: Function name
samples: Number of profiling samples
time_ms: Time in milliseconds
pct: Percentage of total time
p <- pv_example() pv_self_time(p) # Only functions with >= 5% self-time pv_self_time(p, min_pct = 5)p <- pv_example() pv_self_time(p) # Only functions with >= 5% self-time pv_self_time(p, min_pct = 5)
Displays source code around a specific file and line number with profiling information for each line.
pv_source_context(x, filename, linenum = NULL, context = 10)pv_source_context(x, filename, linenum = NULL, context = 10)
x |
A profvis object. |
filename |
The source file to examine. |
linenum |
The line number to center on. If |
context |
Number of lines to show before and after. |
Invisibly returns a debrief_source_context object. Use
capture.output() to capture the formatted text output.
p <- pv_example() pv_source_context(p, "R/main.R", linenum = 10)p <- pv_example() pv_source_context(p, "R/main.R", linenum = 10)
Analyzes the profile and generates specific, actionable optimization suggestions based on detected patterns and hotspots.
pv_suggestions(x)pv_suggestions(x)
x |
A profvis object. |
A data frame with columns:
priority: 1 (highest) to 5 (lowest)
category: Type of optimization (e.g., "data structure", "algorithm")
location: Where to apply the optimization
action: What to do
pattern: Code pattern to look for (or NA)
replacement: Suggested replacement (or NA)
potential_impact: Estimated time that could be saved
p <- pv_example("gc") pv_suggestions(p)p <- pv_example("gc") pv_suggestions(p)
Exports profiling analysis results in JSON format for consumption by AI agents, automated tools, or external applications.
pv_to_json( x, file = NULL, pretty = TRUE, include = c("summary", "self_time", "total_time", "hot_lines", "memory", "gc_pressure", "suggestions", "recursive"), system_info = FALSE )pv_to_json( x, file = NULL, pretty = TRUE, include = c("summary", "self_time", "total_time", "hot_lines", "memory", "gc_pressure", "suggestions", "recursive"), system_info = FALSE )
x |
A profvis object. |
file |
Optional file path to write JSON to. If |
pretty |
If |
include |
Character vector specifying which analyses to include. Options: "summary", "self_time", "total_time", "hot_lines", "memory", "callers", "gc_pressure", "suggestions", "recursive". Default includes all. |
system_info |
If |
If file is NULL, returns a JSON string. Otherwise writes to file
and returns the file path invisibly.
p <- pv_example() json <- pv_to_json(p) cat(json) # Include only specific analyses json <- pv_to_json(p, include = c("self_time", "hot_lines")) # Include system info for reproducibility json <- pv_to_json(p, system_info = TRUE)p <- pv_example() json <- pv_to_json(p) cat(json) # Include only specific analyses json <- pv_to_json(p, include = c("self_time", "hot_lines")) # Include system info for reproducibility json <- pv_to_json(p, system_info = TRUE)
Returns all profiling analysis results as a nested R list, useful for programmatic access to results without JSON serialization.
pv_to_list( x, include = c("summary", "self_time", "total_time", "hot_lines", "memory", "gc_pressure", "suggestions", "recursive"), system_info = FALSE )pv_to_list( x, include = c("summary", "self_time", "total_time", "hot_lines", "memory", "gc_pressure", "suggestions", "recursive"), system_info = FALSE )
x |
A profvis object. |
include |
Character vector specifying which analyses to include.
Same options as |
system_info |
If |
A named list containing the requested analyses.
p <- pv_example() results <- pv_to_list(p) names(results) results$self_timep <- pv_example() results <- pv_to_list(p) names(results) results$self_time
Returns the time spent in each function including all its callees. This shows which functions are on the call stack when time is being spent.
pv_total_time(x, n = NULL, min_pct = 0, min_time_ms = 0)pv_total_time(x, n = NULL, min_pct = 0, min_time_ms = 0)
x |
A profvis object. |
n |
Maximum number of functions to return. If |
min_pct |
Minimum percentage of total time to include (default 0). |
min_time_ms |
Minimum time in milliseconds to include (default 0). |
A data frame with columns:
label: Function name
samples: Number of profiling samples where function appeared
time_ms: Time in milliseconds
pct: Percentage of total time
p <- pv_example() pv_total_time(p) # Only functions with >= 50% total time pv_total_time(p, min_pct = 50)p <- pv_example() pv_total_time(p) # Only functions with >= 50% total time pv_total_time(p, min_pct = 50)
Returns the hottest source line with full context. Useful for quickly identifying the #1 optimization target.
pv_worst_line(x, context = 5)pv_worst_line(x, context = 5)
x |
A profvis object. |
context |
Number of source lines to include before and after. |
A list with:
location: File path and line number (e.g., "R/foo.R:42")
label: Function name
filename: Source file path
linenum: Line number
time_ms: Time in milliseconds
pct: Percentage of total time
code: The source line
context: Vector of surrounding source lines
callers: Data frame of functions that call this location
Returns NULL if no source references are available.
p <- pv_example() pv_worst_line(p)p <- pv_example() pv_worst_line(p)