Nushell
Get Nu!
Getting Started
  • The Nushell Book
  • Command Reference
  • Cookbook
  • Language Reference Guide
  • Contributing Guide
Blog
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
GitHub
Get Nu!
Getting Started
  • The Nushell Book
  • Command Reference
  • Cookbook
  • Language Reference Guide
  • Contributing Guide
Blog
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
GitHub
  • Categories

    • Bits
    • Bytes
    • Chart
    • Conversions
    • Core
    • Database
    • Dataframe
    • Dataframe Or Lazyframe
    • Date
    • Debug
    • Default
    • Env
    • Experimental
    • Expression
    • Filesystem
    • Filters
    • Formats
    • Generators
    • Hash
    • History
    • Lazyframe
    • Math
    • Misc
    • Network
    • Path
    • Platform
    • Plugin
    • Prompt
    • Random
    • Removed
    • Shells
    • Strings
    • System
    • Viewers

debug profile for debug

Profile pipeline elements in a closure.

Signature

> debug profile {flags} (closure)

Flags

  • --spans, -s: Collect spans of profiled elements
  • --expand-source, -e: Collect full source fragments of profiled elements
  • --values, -v: Collect pipeline element output values
  • --lines, -l: Collect line numbers
  • --duration-values, -d: Report instruction duration as duration values rather than milliseconds
  • --max-depth, -m {int}: How many blocks/closures deep to step into (default 2)

Parameters

  • closure: The closure to profile.

Input/output types:

inputoutput
anytable

Examples

Profile config evaluation

> debug profile { source $nu.config-path }

Profile config evaluation with more granularity

> debug profile { source $nu.config-path } --max-depth 4

Notes

The profiler profiles every evaluated instruction inside a closure, stepping into all commands calls and other blocks/closures.

The output can be heavily customized. By default, the following columns are included:

  • depth : Depth of the instruction. Each entered block adds one level of depth. How many blocks deep to step into is controlled with the --max-depth option.
  • id : ID of the instruction
  • parent_id : ID of the instruction that created the parent scope
  • source : Source code that generated the instruction. If the source code has multiple lines, only the first line is used and ... is appended to the end. Full source code can be shown with the --expand-source flag.
  • pc : The index of the instruction within the block.
  • instruction : The pretty printed instruction being evaluated.
  • duration : How long it took to run the instruction.
  • (optional) span : Span associated with the instruction. Can be viewed via the view span command. Enabled with the --spans flag.
  • (optional) output : The output value of the instruction. Enabled with the --values flag.

To illustrate the depth and IDs, consider debug profile { do { if true { echo 'spam' } } }. A unique ID is generated each time an instruction is executed, and there are two levels of depth:

depth   id   parent_id                    source                     pc            instruction
    0    0           0   debug profile { do { if true { 'spam' } } }  0   <start>
    1    1           0   { if true { 'spam' } }                       0   load-literal    %1, closure(2164)
    1    2           0   { if true { 'spam' } }                       1   push-positional %1
    1    3           0   { do { if true { 'spam' } } }                2   redirect-out    caller
    1    4           0   { do { if true { 'spam' } } }                3   redirect-err    caller
    1    5           0   do                                           4   call            decl 7 "do", %0
    2    6           5   true                                         0   load-literal    %1, bool(true)
    2    7           5   if                                           1   not             %1
    2    8           5   if                                           2   branch-if       %1, 5
    2    9           5   'spam'                                       3   load-literal    %0, string("spam")
    2   10           5   if                                           4   jump            6
    2   11           5   { if true { 'spam' } }                       6   return          %0
    1   12           0   { do { if true { 'spam' } } }                5   return          %0

Each block entered increments depth by 1 and each block left decrements it by one. This way you can control the profiling granularity. Passing --max-depth=1 to the above would stop inside the do at if true { 'spam' }. The id is used to identify each element. The parent_id tells you that the instructions inside the block are being executed because of do (5), which in turn was spawned from the root debug profile { ... }.

For a better understanding of how instructions map to source code, see the view ir command.

Note: In some cases, the ordering of pipeline elements might not be intuitive. For example, [ a bb cc ] | each { $in | str length } involves some implicit collects and lazy evaluation confusing the id/parent_id hierarchy. The --expr flag is helpful for investigating these issues.