Git Product home page Git Product logo

flameprof's Introduction

Flamegraph generator for python's cProfile stats.

Flamegraphs allow to visualize relations between functions in a very compact and understandable manner.

Flameprof solves main problems of built-in cProfile reporting and can replace gprof2dot because later outputs very huge graphs with a lot of noise.

Flameprof works with profile stat files obtained by Profile.dump_stats() call or via direct script profiling:

python -m cProfile -o myscript.prof myscript.py

Install

Via pip:

pip install flameprof

Or you can invoke flameprof.py directly:

python flameprof.py input.prof > output.svg

Native svg (--format=svg)

Native svg features:

  • compact function names with full names in a tooltip
  • precise timings (cumulative and total)
  • call counts (in a tooltip on hover)
  • green bars show stack frames where flameprof starts to guess timing ratios
  • inverted flamegraph to show total time of all calls

Graph width, row height, font size and threshold can be set via appropriate cli options.

flameprof requests.prof > requests.svg

Requests profile

Inverted flamegraph:

Requests profile

(Images are clickable)

Svg generated with flamegraph.pl (--format=log)

Also flameprof can output trace log suitable as input for flamegraph.pl.

You can treat "samples" as microseconds by default (see --log-mult option).

flameprof --format=log requests.prof | flamegraph > requests-flamegraph.svg

Requests profile with flamegraph.pl

(Image is clickable)

flameprof's People

Contributors

baverman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

flameprof's Issues

What do the numbers in parentheses mean

<title>test.py:15:test_recursion 22.93% (6 0 4.222224027306071e-05 0.2833811705771583)</title>

I understand that the last two numbers may be tottime and cumtime corresponding to the profile, and the first number may be ncalls, so what is the second number 0?


def test_recursion(num):
    if num < 0:
        return
    print('test_recursion', num)
    time.sleep(0.1)
    test_recursion(num-1)
    test_recursion(num-3)


def main():
    test_recursion(5)


if __name__ == "__main__":
    main()

ZeroDivisionError: float division by zero

when i try to render the svg file by myself, i got exception like this

  File "profmiddleware.py", line 37, in post_prof
    flameprof.render(pr.stats, flameprof.get_out(svg_file_name))
  File "/home/cpys/anaconda3/lib/python3.8/site-packages/flameprof.py", line 305, in render
    blocks, bblocks, maxw = prepare(funcs, calls, threshold=threshold)
  File "/home/cpys/anaconda3/lib/python3.8/site-packages/flameprof.py", line 232, in prepare
    _calc_back((f for f in funcs if f != 'root'), 0, None, 0, set(), 0)
  File "/home/cpys/anaconda3/lib/python3.8/site-packages/flameprof.py", line 225, in _calc_back
    _calc_back(func['called'], level+1, name, origin, visited | {key}, ttt)
  File "/home/cpys/anaconda3/lib/python3.8/site-packages/flameprof.py", line 225, in _calc_back
    _calc_back(func['called'], level+1, name, origin, visited | {key}, ttt)
  File "/home/cpys/anaconda3/lib/python3.8/site-packages/flameprof.py", line 225, in _calc_back
    _calc_back(func['called'], level+1, name, origin, visited | {key}, ttt)
  [Previous line repeated 2 more times]
  File "/home/cpys/anaconda3/lib/python3.8/site-packages/flameprof.py", line 199, in _calc_back
    factor = pw / sum(calls[(r, to)][3] for r in names)
ZeroDivisionError: float division by zero
flameprof.render(pr.stats, flameprof.get_out(svg_file_name))

Make SVG-generating more general

If you ever have a little free time—

I'd like to use the SVG-generating code not for pstats, but for my own datastructures (see itamarst/eliot#220).

My original thought was to generate Pstats instances and then use your code, but the Pstats class internals don't guarantee stability it seems?

More broadly, there are a bunch of Python projects that currently rely on flamegraph.pl and might benefit from pure-Python flamegraph SVG generating code, separate from the pstats-specific code.

Flameprof is failing to parse profile output

Hi,

I'd like to tell people about flameprof in talk I'm giving, but it's failing for me:

$ python -m cProfile -o out.prof benchmarks/serialization.py
$ flameprof out.prof > prof.svg
Warning: flameprof can't find proper roots, root cumtime is 0.0 but sum tottime is 1.6221999999999899

I'm specifically running the benchmark from https://github.com/itamarst/eliot

Stack filtering

When using cprofile as a CLI, there can be lots of intermediate or ancillary noise in the profile. The ability to filter stacks become very useful then.

It's doable using —format=log and flamegraph.pl as the flamegraph log is a list of stacks so a simple grep works, but that means not getting the improvements of flameprof's "native" SVG (especially getting the reverse graph alongside the normal one).

Installed tool requires that `python` be the correct executable

Description

pip install flameprof requires that python be the correct version of the executable. For those of us running python3 where python still points to python2, this causes a problem.

Steps to reproduce

  1. On macOS 10.15 running python3 from homebrew, run pip3 install --user flameprof
  2. $ cat $(which flameprof) will output:
    #!/bin/sh
    exec python -m flameprof "$@"
    
  3. python --version will output Python 2.7.17

Proposed solution

The first way I can think of to solve this is to write the contents of flameprof with an explicit version numbered interpreter, IE: python2 or python3, as determined by the version running when installed. That seems fragile, but less fragile than what exists today.

flameprof sometimes records impossible stacks

Hi, I'm attempting to benchmark a project, and I'm getting a really weird result. There are call paths in the flame graph that cannot really be part of the program. Here's a minimal, self-contained example of my problem:

import cProfile
import subprocess


def a():
    s = 0
    for i in range(1000):
        s += i
    return s


def b():
    s = 0
    for i in range(1000):
        s += i ** 2
    return s


def dispatch(func):
    return func()


def a_caller():
    return dispatch(a)


def b_caller():
    return dispatch(b)


def to_profile():
    return a_caller() + b_caller()


stats_file = 'test.prof'
flame_file = 'test.svg'
cProfile.run('to_profile()', stats_file)
subprocess.check_call(f'flameprof {stats_file} > {flame_file}', shell=True)

In this program, the function a_caller() calls a(), and the function b_caller() calls b(). There is no path for a_caller() to call b(), although the function dispatch() will appear on both stacks.

This is what the profile looks like:

test

The profile reports that a_caller() spends most of its time inside of b(). Removing dispatch() and calling a() or b() directly provides the correct result.

This is a problem for me because any numpy operation I do goes through a single numpy function, <built-in method numpy.core._multiarray_umath.implement_array_function>. For example, in this part of the trace, I'm calling np.repeat(). As far as I know, that shouldn't invoke cumsum(), hstack(), or delete().

Screenshot from 2022-12-20 14-05-53

Any ideas on how to improve this, or things I might be doing wrong? Is this just an intrinsic limitation of cProfile?

Speedscope support

While I do love the feature to export the data as an SVG file, a more interactive way would be to load the data into speedscope. I would love to build a small parser, which parses a cProfile dump into a speedscope json file following its schema.

Could you maybe explain me what parts in the code are mainly doing the parsing so I could implement it myself?

Thanks :)

Hey, this is not really an issue. But I wanted to let you know that I started using this and it's very useful, thanks for writing it! :)

I'm using it as a library by importing render and rendering to a StringIO, and then embedding the resulting SVG.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.