How does function inlining reflect on the profiling output?

I have a Julia program. It includes a big function which calls another, small, function in two places.
Profiling the execution and displaying a flame graph with ProfileView shows that most of the time is spent in the small function.
So I wonder, if a function appears in the profiling output, does that mean that it wasn’t inlined? In other words, how are inlined functions accounted for in profiling?

Here’s a demo that should answer your questions:

julia> function f()
           inline_me()
           dont_inline_me()
       end
       inline_me() = sleep(0.1)
       @noinline dont_inline_me() = sleep(0.1)
dont_inline_me (generic function with 1 method)

julia> using Profile

julia> @profile f()

julia> using ProfileView

julia> ProfileView.view()
Gtk.GtkWindowLeaf(name="", parent, width-request=-1, height-request=-1, visible=TRUE, sensitive=TRUE, app-paintable=FALSE, can-focus=FALSE, has-focus=FALSE, is-focus=FALSE, focus-on-click=TRUE, can-default=FALSE, has-default=FALSE, receives-default=FALSE, composite-child=FALSE, style, events=0, no-show-all=FALSE, has-tooltip=FALSE, tooltip-markup=NULL, tooltip-text=NULL, window, opacity=1.000000, double-buffered, halign=GTK_ALIGN_FILL, valign=GTK_ALIGN_FILL, margin-left, margin-right, margin-start=0, margin-end=0, margin-top=0, margin-bottom=0, margin=0, hexpand=FALSE, vexpand=FALSE, hexpand-set=FALSE, vexpand-set=FALSE, expand=FALSE, scale-factor=1, border-width=0, resize-mode, child, type=GTK_WINDOW_TOPLEVEL, title="Profile", role=NULL, resizable=TRUE, modal=FALSE, window-position=GTK_WIN_POS_NONE, default-width=800, default-height=600, destroy-with-parent=FALSE, hide-titlebar-when-maximized=FALSE, icon, icon-name=NULL, screen, type-hint=GDK_WINDOW_TYPE_HINT_NORMAL, skip-taskbar-hint=FALSE, skip-pager-hint=FALSE, urgency-hint=FALSE, accept-focus=TRUE, focus-on-map=TRUE, decorated=TRUE, deletable=TRUE, gravity=GDK_GRAVITY_NORTH_WEST, transient-for, attached-to, has-resize-grip, resize-grip-visible, application, is-active=TRUE, has-toplevel-focus=TRUE, startup-id, mnemonics-visible=FALSE, focus-visible=FALSE, is-maximized=FALSE)

julia> ./REPL[1]:5, inline_me [inlined]
./REPL[1]:6, MethodInstance for dont_inline_me()

The last two lines come from left-clicking on bars in the flamegraph:

You can see one is annotated [inlined], but nevertheless shows up with its own separate (fake) bar. In other words, we’ve worked hard to lie to you :slightly_smiling_face: but it’s generally more useful that way (inlining is a compiler optimization and doesn’t affect the actual writing of code).

4 Likes