Skip to content

Commit 9244783

Browse files
authored
Merge pull request #299 from pythonspeed/various-documentation-improvements
Various documentation improvements
2 parents 9286174 + 82f01eb commit 9244783

File tree

6 files changed

+44
-17
lines changed

6 files changed

+44
-17
lines changed

.changelog/185.doc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improved explanations in report of what it is that Fil tracks, and what a flamegraph tells you.

.changelog/291.doc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix bad command name in the API documentation, thanks to @kdebrab.

.changelog/292.misc

Whitespace-only changes.

.changelog/298.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Reports now have a "open in new tab" button. Thanks to @petergaultney for the suggestion.

docs/src/fil/api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ $ python yourscript.py --config=myconfig
5959
Now you would do:
6060

6161
```console
62-
$ filprofiler python yourscript.py --config=myconfig
62+
$ fil-profile python yourscript.py --config=myconfig
6363
```
6464

65-
Notice that you're doing `filprofiler `**`python`**, rather than `filprofiler run` as you would if you were profiling the full script.
65+
Notice that you're doing `fil-profile `**`python`**, rather than `fil-profile run` as you would if you were profiling the full script.
6666
Only functions running for the duration of the `filprofiler.api.profile()` call will have memory profiling enabled, including of course the function you pass in.
6767
The rest of the code will run at (close) to normal speed and configuration.
6868

filprofiler/_report.py

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def render_report(output_path: str, now: datetime) -> str:
4040
margin: 4rem auto;
4141
font-size: 18px;
4242
}}
43-
blockquote {{ border: 1px; border-color: black; }}
43+
blockquote {{ border-width: 1px; border-color: black; border-style: solid; padding: 1em; }}
4444
div {{
4545
text-align: center;
4646
}}
@@ -74,42 +74,66 @@ def render_report(output_path: str, now: datetime) -> str:
7474
<p><code>{argv}</code><p>
7575
7676
<h2>Profiling result</h2>
77-
<div><iframe id="peak" src="peak-memory.svg" width="100%" height="400" scrolling="auto" frameborder="0"></iframe><br>
78-
<p><input type="button" onclick="fullScreen('#peak');" value="Full screen"></p></div>
79-
77+
<div><p><input type="button" onclick="fullScreen('#peak');" value="Full screen"> · <a href="peak-memory.svg" target="_blank"><button>Open in new window</button></a></p>
78+
<iframe id="peak" src="peak-memory.svg" width="100%" height="400" scrolling="auto" frameborder="0"></iframe><br>
79+
</div>
80+
<br>
81+
<br>
82+
<hr>
83+
<br>
84+
<div><p><input type="button" onclick="fullScreen('#peak-reversed');" value="Full screen"> · <a href="peak-memory-reversed.svg" target="_blank"><button>Open in new window</button></a></p>
85+
<iframe id="peak-reversed" src="peak-memory-reversed.svg" width="100%" height="400" scrolling="auto" frameborder="0"></iframe><br>
86+
</div>
8087
<br>
8188
<blockquote><strong>Need help, or does something look wrong?</strong>
8289
<a href="https://pythonspeed.com/fil/docs/">Read the documentation</a>,
8390
and if that doesn't help please
8491
<a href="https://github.com/pythonspeed/filprofiler/issues/new?body={bugreport}">file an issue</a>
8592
and I'll try to help.</blockquote>
86-
<br>
87-
88-
<div><iframe id="peak-reversed" src="peak-memory-reversed.svg" width="100%" height="400" scrolling="auto" frameborder="0"></iframe><br>
89-
<p><input type="button" onclick="fullScreen('#peak-reversed');" value="Full screen"></p></div>
90-
9193
<br>
9294
<blockquote><strong>Want memory and performance profiling for your production batch jobs?</strong>
93-
I'm working on a
94-
<a href="https://pythonspeed.com/products/fil4prod/"
95-
>always-on profiler called Fil4prod</a> that is fast and robust enough to run in production;
96-
<a href="mailto:[email protected]">send me an email</a> to participate
97-
in the alpha program.</blockquote>
95+
I've also created an
96+
<a href="https://pythonspeed.com/sciagraph/"
97+
>always-on profiler called Sciagraph</a> that is fast and robust enough to run in production.</blockquote>
9898
<br>
9999
100+
<h2>Learn how to reduce memory usage</h2>
101+
102+
<p>Need help reducing your data processing application's memory use? Check out tips and tricks <a href="https://pythonspeed.com/memory/">here</a>.</p>
103+
100104
<h2>Understanding the graphs</h2>
101105
<p>The flame graphs shows the callstacks responsible for allocations at peak.</p>
102106
103107
<p>The wider (and the redder) the bar, the more memory was allocated by that function or its callers.
104108
If the bar is 100% of width, that's all the allocated memory.</p>
105109
110+
<p>The left-right axis has no meaning!
111+
The order of frames is somewhat arbitrary, for example beause multiple calls to the same function may well have been merged into a single callstack.
112+
So you can't tell from the graph which allocations happened first.
113+
All you're getting is that at peak allocation these time, these stacktraces were responsible for these allocations.
114+
</p>
115+
106116
<p>The first graph shows the normal callgraph: if <tt>main()</tt> calls <tt>g()</tt> calls <tt>f()</tt>, let's say, then <tt>main()</tt> will be at the top.
107117
The second graph shows the reverse callgraph, from <tt>f()</tt> upwards.</p>
108118
109119
<p>Why is the second graph useful? If <tt>f()</tt> is called from multiple places, in the first graph it will show up multiple times, at the bottom.
110120
In the second reversed graph all calls to <tt>f()</tt> will be merged together.</p>
111121
112-
<p>Need help reducing your data processing application's memory use? Check out tips and tricks <a href="https://pythonspeed.com/memory/">here</a>.</p>
122+
<h2>Understanding what Fil tracks</h2>
123+
124+
<p>Fil measures how much memory has been allocated; this is not the same as how much memory the process is actively using, nor is it the same as memory resident in RAM.</p>
125+
126+
<ul>
127+
<li>If the data gets dumped from RAM to swap, Fil still counts it but it's not counted as resident in RAM.</li>
128+
<li>If the memory is a large chunk of all zeros, on Linux no RAM is used by OS until you actually modify that memory, but Fil will still count it.</li>
129+
<li>If you have memory that only gets freed on garbage collection
130+
(this will happen if you have circular references in your data structures),
131+
memory can be freed at inconsistent times across different runs, especially
132+
if you're using threads.</li>
133+
</ul>
134+
135+
<p>See <a href="https://pythonspeed.com/articles/measuring-memory-python/">this article</a> for more details.</p>
136+
113137
</body>
114138
</html>
115139
""".format(

0 commit comments

Comments
 (0)