<p>Before digging into this section, remember Donald Knuth’s <aclass="reference external"href="https://en.wikipedia.org/wiki/Program_optimization#When_to_optimize">words of
<p>Python’s <codeclass="docutils literal notranslate"><spanclass="pre">timeit</span></code> module is very good for testing small things. For example, in order to test if it
is faster to use a <codeclass="docutils literal notranslate"><spanclass="pre">for</span></code> loop or a list comprehension you could use the following code:</p>
<spanclass="c1"># Time to do 1000000 for loops</span>
<spanclass="n">timeit</span><spanclass="o">.</span><spanclass="n">timeit</span><spanclass="p">(</span><spanclass="s2">"for i in range(100):</span><spanclass="se">\n</span><spanclass="s2"> a.append(i)"</span><spanclass="p">,</span><spanclass="n">setup</span><spanclass="o">=</span><spanclass="s2">"a = []"</span><spanclass="p">)</span>
<spanclass="c1"># Time to do 1000000 list comprehensions</span>
<spanclass="n">timeit</span><spanclass="o">.</span><spanclass="n">timeit</span><spanclass="p">(</span><spanclass="s2">"a = [i for i in range(100)]"</span><spanclass="p">)</span>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">setup</span></code> keyword is used to set up things that should not be included in the time measurement,
like <codeclass="docutils literal notranslate"><spanclass="pre">a</span><spanclass="pre">=</span><spanclass="pre">[]</span></code> in the first call.</p>
<p>By default the <codeclass="docutils literal notranslate"><spanclass="pre">timeit</span></code> function will re-run the given test 1000000 times and returns the <em>total
time</em> to do so (so <em>not</em> the average per test). A hint is to not use this default for testing
something that includes database writes - for that you may want to use a lower number of repeats
(say 100 or 1000) using the <codeclass="docutils literal notranslate"><spanclass="pre">number=100</span></code> keyword.</p>
<p>Python comes with its own profiler, named cProfile (this is for cPython, no tests have been done
with <codeclass="docutils literal notranslate"><spanclass="pre">pypy</span></code> at this point). Due to the way Evennia’s processes are handled, there is no point in
using the normal way to start the profiler (<codeclass="docutils literal notranslate"><spanclass="pre">python</span><spanclass="pre">-m</span><spanclass="pre">cProfile</span><spanclass="pre">evennia.py</span></code>). Instead you start the
<p>This will start Evennia with the Server component running (in daemon mode) under cProfile. You could
instead try <codeclass="docutils literal notranslate"><spanclass="pre">--profile</span></code> with the <codeclass="docutils literal notranslate"><spanclass="pre">portal</span></code> argument to profile the Portal (you would then need to
<p>Please note that while the profiler is running, your process will use a lot more memory than usual.
Memory usage is even likely to climb over time. So don’t leave it running perpetually but monitor it
carefully (for example using the <codeclass="docutils literal notranslate"><spanclass="pre">top</span></code> command on Linux or the Task Manager’s memory display on
Windows).</p>
<p>Once you have run the server for a while, you need to stop it so the profiler can give its report.
Do <em>not</em> kill the program from your task manager or by sending it a kill signal - this will most
likely also mess with the profiler. Instead either use <codeclass="docutils literal notranslate"><spanclass="pre">evennia.py</span><spanclass="pre">stop</span></code> or (which may be even
better), use <codeclass="docutils literal notranslate"><spanclass="pre">@shutdown</span></code> from inside the game.</p>
<p>Once the server has fully shut down (this may be a lot slower than usual) you will find that
profiler has created a new file <codeclass="docutils literal notranslate"><spanclass="pre">mygame/server/logs/server.prof</span></code>.</p>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">server.prof</span></code> file is a binary file. There are many ways to analyze and display its contents,
all of which has only been tested in Linux (If you are a Windows/Mac user, let us know what works).</p>
<aclass="reference external"href="http://www.vrplumber.com/programming/runsnakerun/">Runsnake</a> visualizer to see the processor usage
of different processes in a graphical form. For more detailed listing of usage time, you can use
<aclass="reference external"href="http://kcachegrind.sourceforge.net/html/Home.html">KCachegrind</a>. To make KCachegrind work with
Python profiles you also need the wrapper script
<aclass="reference external"href="https://pypi.python.org/pypi/pyprof2calltree/">pyprof2calltree</a>. You can get pyprof2calltree via
<codeclass="docutils literal notranslate"><spanclass="pre">pip</span></code> whereas KCacheGrind is something you need to get via your package manager or their homepage.</p>
<p>How to analyze and interpret profiling data is not a trivial issue and depends on what you are
profiling for. Evennia being an asynchronous server can also confuse profiling. Ask on the mailing
list if you need help and be ready to be able to supply your <codeclass="docutils literal notranslate"><spanclass="pre">server.prof</span></code> file for comparison,
along with the exact conditions under which it was obtained.</p>
<p>The first time you do this you will most likely get a warning from Dummyrunner. It will tell you to
copy an import string to the end of your settings file. Quit the Dummyrunner (<codeclass="docutils literal notranslate"><spanclass="pre">Ctrl-C</span></code>) and follow
the instructions. Restart Evennia and try <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">--dummyrunner</span><spanclass="pre">10</span></code> again. Make sure to remove that
extra settings line when running a public server.</p>
<p>The actions perform by the dummies is controlled by a settings file. The default Dummyrunner
settings file is <codeclass="docutils literal notranslate"><spanclass="pre">evennia/server/server/profiling/dummyrunner_settings.py</span></code> but you shouldn’t modify
this directly. Rather create/copy the default file to <codeclass="docutils literal notranslate"><spanclass="pre">mygame/server/conf/</span></code> and modify it there. To
make sure to use your file over the default, add the following line to your settings file:</p>