Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: add a renderer to save python-profile prof files #236

Merged
merged 14 commits into from May 11, 2023

Conversation

mattip
Copy link
Contributor

@mattip mattip commented Apr 9, 2023

Closes #64. Now running python -m pyinstrument -r prof -o <filename> <script> will create a file compatible with python -m profile -o <filename> <script>. It can be loaded into tools like gprof2dot and snakeviz for visualization.

Of course the ncall number is bogus. I used -1. Since we only know total time, the percall time is also not available. Ideas for further tests or correcting the statistics are welcome.

Copy link
Owner

@joerick joerick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Matti! Thanks for this, it looks good. Would it be possible to add just a test that checks that pstats.Stats doesn't crash when loading the output of a simple script?

pyinstrument/__main__.py Outdated Show resolved Hide resolved
pyinstrument/renderers/profrenderer.py Outdated Show resolved Hide resolved
pyinstrument/renderers/profrenderer.py Outdated Show resolved Hide resolved
@mattip
Copy link
Contributor Author

mattip commented Apr 12, 2023

I responded to the review and added a test

@mattip
Copy link
Contributor Author

mattip commented Apr 17, 2023

I think this is ready for another round of review. Perhaps enabling the CI run would give some confidence that the tests are correct?

@joerick
Copy link
Owner

joerick commented Apr 17, 2023

Thanks and apologies for the delay! I'll try to look in the next few days

Copy link
Owner

@joerick joerick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is complicated by the fact that the prof renderer outputs bytes, not strs. I'll have a think how we can resolve this neatly.

pyinstrument/__main__.py Outdated Show resolved Hide resolved
@joerick
Copy link
Owner

joerick commented Apr 25, 2023

I've pushed some fixes to this, if you get a sec could you check this is still working for you @mattip? There were a couple issues with the prof rendering as well as some internal issues (like total_self_time always returning zero), but I think I got them all.

@mattip
Copy link
Contributor Author

mattip commented Apr 26, 2023

I think this looks good on a toy script I tried. Is there any end-to-end testing you do offline to verify that the renderers all give similar results?

@joerick
Copy link
Owner

joerick commented Apr 26, 2023 via email

@mattip
Copy link
Contributor Author

mattip commented Apr 27, 2023

maybe there's some way to visualise the call graph

Running the code in the new test, and then using gprof2dot

gprof2dot -f pstats /tmp/test_renderer.prof | dot -Tpng -o /tmp/output.png

I get
output

@mattip
Copy link
Contributor Author

mattip commented Apr 27, 2023

Sorry, that was cProfile. The ProfRenderer from pyinstrument gives me this. Note the 50% -1 in the call to e and sleep. I wonder what is wrong

output

@joerick
Copy link
Owner

joerick commented Apr 27, 2023

nice, thank you! well the "-1" is because the number of calls is -1, due to statistical profiling we don't know that. but the 50% below the branches is odd, and looks wrong. Perhaps it is getting confused with the numcalls being -1? we could try 1 to see if that helps. Otherwise it's probably something to do with the callers dict

@joerick
Copy link
Owner

joerick commented Apr 27, 2023

Ah, yeah it must be the callers dict - I made the same mistake as we had with the stats dict - the code overwrites rather than adding to the caller entry. I can try a fix now

@joerick
Copy link
Owner

joerick commented Apr 27, 2023

I thiiiink that might fix it. Are you able to try the viz again?

@mattip
Copy link
Contributor Author

mattip commented Apr 27, 2023

Yes, that did fix the per-cent. The rendering is a bit off, it is hard to read 100%. But that is certainly not pyinstrument's problem :). I think this is about as good as we can do?
output

@joerick
Copy link
Owner

joerick commented Apr 27, 2023

yeah that looks good to me. I'd rather the numcalls said -1 rather than 1 or 0 as it's clear that there is no data.

I think i'd like some more detailed unit tests on the things we've discovered during this PR about the pstats file format. mostly, just basic stuff around frames, timings, and asserting that the fix we made above still holds. If you have time, that would be great, otherwise I'll get around to it at some point.

Something else I'd wondering - is pstats a better name for this than prof?

@mattip
Copy link
Contributor Author

mattip commented Apr 27, 2023

is pstats a better name for this than prof?

yes, I am horrible at naming things. I will take a look at adding tests. Since the stats output is a dictionary, I think it should be straightforward to assert some of what you suggest.

@mattip
Copy link
Contributor Author

mattip commented May 3, 2023

Added some tests and renamed the renderer.

@joerick
Copy link
Owner

joerick commented May 5, 2023

These test errors can be circumvented using fake time. I can look at that now

@mattip
Copy link
Contributor Author

mattip commented May 10, 2023

Any idea why the readthedocs build failed?

@joerick
Copy link
Owner

joerick commented May 10, 2023

I fixed that in #239, should be resolved by merging main.

@mattip
Copy link
Contributor Author

mattip commented May 10, 2023

Rebased off main, and CI is passing.

Copy link
Owner

@joerick joerick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking over the diff, still a few instances of the renderer referred to as 'prof' and not pstats

@mattip
Copy link
Contributor Author

mattip commented May 10, 2023

Good catch. I changed the file extension for this renderer to *.pstats.

@joerick
Copy link
Owner

joerick commented May 11, 2023

Looks good! Thanks @mattip !

@joerick joerick merged commit d117a56 into joerick:main May 11, 2023
21 checks passed
@mattip
Copy link
Contributor Author

mattip commented May 11, 2023

Thanks for shepherding this through to the end.

@mattip
Copy link
Contributor Author

mattip commented May 24, 2023

Is there a plan for a new release?

@joerick
Copy link
Owner

joerick commented May 26, 2023

Sorry for the wait, gonna get #240 in and then cut a new release

@mattip
Copy link
Contributor Author

mattip commented May 27, 2023

Cool, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature Request: pstats output
2 participants