Add speedscope renderer by goxberry · Pull Request #160 · joerick/pyinstrument
This commit starts the implementation of a speedscope renderer by: * copying the existing JSONRenderer to a new SpeedscopeRenderer class in `speedscope.py` of the `renderers` directory * adding an import hook to `__init__.py` of the `renderers` directory * adding a `speedscope` option to the `-r` flag at the command line
This commit deletes the jsonrenderer comment in the SpeedscopeRenderer implementation; the source file is obviously not named jsonrenderer.
This commit converts SpeedscopeFrame from a non-class-style namedtuple to a class-style namedtuple for readability.
This commit uncomments the SpeedscopeEventType enumeration class and uses it in the SpeedscopeRenderer implementation.
This commit converts the SpeedscopeEvent namedtuple from non-class-type to class-type to make it more self-documenting and to conform with project guidelines regarding type hints.
This commit revises the docstring for SpeedscopeRenderer.render_frame by deleting text that no longer applies to the implementation of this method.
This commit adds a JSON encoder class for the SpeedscopeEvent namedtuple in order to stand up a SpeedscopeRenderer implementation based on the Python json module.
This commit renames the _total_time field to _event_time in order to clarify its purpose in the SpeedscopeRenderer class.
This commit deletes the encode_speedscope_event function because it is no longer needed, and has been replaced with calls to json.dumps and SpeedscopeEventEncoder.
This commit adds a JSON encoder for the SpeedscopeFrame class to try to stand up a SpeedscopeRenderer implementation that uses the json module.
This commit deletes the import of `collections.namedtuple` because the speedscope renderer now uses class-style namedtuple definitions.
This commit removes type hints from `SpeedscopeEventType` in order to silence some `pyright` errors regarding incorrect types when using `str` as the type hint for each value.
This commit changes the SpeedscopeFrame and SpeedscopeEvent types from class-style namedtuples to dataclasses because I couldn't figure out how to serialize namedtuples to JSON objects via: * subclassing json.JSONEncoder * defining a default method Attempting to return a dictionary using the data in each namedtuple did not seem to yield a string containing a JSON object; instead, a string containing a JSON array was returned. Changing the namedtuple types to dataclasses and leveraging the __dict__ dunder field, in concert with subclassing json.JSONEncoder and defining a default method, yielded the desired result, although memory usage will increase slightly.
This commit adds a SpeedscopeProfile class that stores the data corresponding to speedscope "profile" objects, and adds a SpeedscopeProfileEncoder class to serialize that class to JSON. The encoder classes will be consolidated in a later commit.
This commit deletes the commented-out dead code used by the pure string approach to serializing speedscope profile objects.
This commit adds a SpeedscopeFile data class and a SpeedscopeEncoder class to serialize to JSON the SpeedscopeFrame, SpeedscopeEvent, SpeedscopeProfile, SpeedscopeEventType, and SpeedscopeFile data classes.
This commit revises the SpeedscopeRenderer class by removing a lot of dead code and updating docstrings and comments in the class and its auxiliary classes.
This commit deletes the processor.aggregate_repeated_calls method from the list of default processors returned by SpeedscopeRenderer because speedscope is a timeline-based format, and aggregating repeated calls fouls up a timeline view.
This commit updates a code comment within SpeedscopeRenderer.render discussing why the frame list is constructed as it is.
This commit replaces the for loop that builds up the speedscope frame list with a list comprehension.
This commit removes the dataclass arguments from the SpeedscopeEvent class because this class does not need to be hashable.
This commit modifies the display title of a speedscope profile exported from pyinstrument to include the timestamp of when the profile was generated (which also happens to be argument to `--load-prev` needed to render output in other formats).
This commit changes the SpeedscopeRenderer code to comply with project style guidelines regarding code formatting with black and isort.
This commit fixes an apparent inconsistency in the profiles[0].endValue field of the Speedscope output from SpeedscopeRenderer. In unit testing, the value of session.duration (within a call to SpeedscopeRenderer.render) may not be equal to the event time of the last event in the profiles[0].events field of the Speedscope output. In fact, in the test_speedscope_output test within test_profiler.py, the value of session duration was approximately 0.0047s (in local testing on my laptop), whereas the time value of the last event generated by the profile in that test should be 0.75s +/- 0.3s. To correct this inconsistency, the end value of profile is set equal to the event time of the last event.
This commit adds a test to test_profiler that tests the JSON output emitted by SpeedscopeRenderer against known properties it should have.
This commit: * Removes, in `test/test_profiler.py`, the test of the value of the `"profiles[0].endValue"` field in the Speedscope JSON output. The difference between the value of `profiles[0].endValue` (equal to `session.duration` from the `session` argument passed to `SpeedscopeRenderer.render`) and the time of the last event can be attributed to the `fake_time` context manager used as a mock timer in the profiler/renderer tests. * Changes the value assigned to the `profiles[0].endValue` field via the last positional argument to `SpeedscopeProfile.__init__` from `self._event_time` (which, at that point in `SpeedscopeRenderer.render` equals the last event time) back to `session.duration`. This change is made because the discrepancy between the values of `session.duration` and `self._event_time` can be attributed to the `fake_time` context manager used as a mock timer in the profiler/renderer tests.
This commit aims to make the `test_speedscope_output` test in `test/test_profiler.py` less wordy and more readable by: * deleting message arguments to assertions * replacing local variables with literals or expressions, because many of these variables were motivated by keeping line length low in message arguments passed to assertions * removing tolerances in the pytest.approx calls because CI jitter should not affect timings, and all floating point numbers involved are exactly representable per the IEEE-754 standard
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters