walkmap/docs/codox/dali-performance.html
Simon Brooke f616992191
#3: Massive changes, superstructure now kind-of works
More unit tests now, and they all pass. More work needed, but this is very promising.
2020-05-25 23:55:52 +01:00

171 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>Dali performance</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.ocean.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ocean</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#dali-performance" name="dali-performance"></a>Dali performance</h1>
<p>Notes written while trying to characterise the performance problem in Dali.</p>
<h2><a href="#hypothesis-one-its-the-way-i-format-the-polygons-thats-the-issue" name="hypothesis-one-its-the-way-i-format-the-polygons-thats-the-issue"></a>Hypothesis one: its the way I format the polygons thats the issue</h2>
<p>Firstly, with both versions of <code>stl-&gt;svg</code> using the same version of <code>facet-&gt;svg-poly</code>, i.e. this one:</p>
<pre><code>(defn- facet-&gt;svg-poly
[facet]
[:polygon
{:points (s/join " " (map #(str (:x %) "," (:y %)) (:vertices facet)))}])
</code></pre>
<p>we get this performance using the smaller <code>isle_of_man</code> map:</p>
<pre><code>walkmap.svg=&gt; (def ^:dynamic *preferred-svg-render* :hiccup)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def hiccup (binary-stl-file-&gt;svg "resources/isle_of_man.stl" "resources/isle_of_man.svg")))
20-05-25 09:21:43 mason INFO [walkmap.svg:82] - Generating SVG for :hiccup renderer
20-05-25 09:21:43 mason INFO [walkmap.svg:96] - Emitting SVG with :hiccup renderer
"Elapsed time: 86.904891 msecs"
#'walkmap.svg/hiccup
walkmap.svg=&gt; (def ^:dynamic *preferred-svg-render* :dali)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def dali (binary-stl-file-&gt;svg "resources/isle_of_man.stl" "resources/isle_of_man.svg")))
20-05-25 09:22:17 mason INFO [walkmap.svg:82] - Generating SVG for :dali renderer
20-05-25 09:22:17 mason INFO [walkmap.svg:96] - Emitting SVG with :dali renderer
"Elapsed time: 890.863814 msecs"
#'walkmap.svg/dali
</code></pre>
<p>If we switch the Dali render to use my original version of <code>facet-&gt;svg-poly</code>, i.e. this one:</p>
<pre><code>(defn- dali-facet-&gt;svg-poly
[facet]
(vec
(cons
:polygon
(map #(vec (list (:x %) (:y %))) (:vertices facet)))))
</code></pre>
<p>we get this performance:</p>
<pre><code>walkmap.svg=&gt; (def ^:dynamic *preferred-svg-render* :hiccup)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def hiccup (binary-stl-file-&gt;svg "resources/isle_of_man.stl" "resources/isle_of_man.svg")))
20-05-25 09:35:33 mason INFO [walkmap.svg:82] - Generating SVG for :hiccup renderer
20-05-25 09:35:33 mason INFO [walkmap.svg:96] - Emitting SVG with :hiccup renderer
"Elapsed time: 84.09972 msecs"
#'walkmap.svg/hiccup
walkmap.svg=&gt; (def ^:dynamic *preferred-svg-render* :dali)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def dali (binary-stl-file-&gt;svg "resources/isle_of_man.stl" "resources/isle_of_man.svg")))
20-05-25 09:35:41 mason INFO [walkmap.svg:82] - Generating SVG for :dali renderer
20-05-25 09:35:41 mason INFO [walkmap.svg:96] - Emitting SVG with :dali renderer
"Elapsed time: 874.292007 msecs"
#'walkmap.svg/dali
</code></pre>
<p>No significant difference in performance.</p>
<p>If we generate but dont render, we get this:</p>
<pre><code>walkmap.svg=&gt; (def ^:dynamic *preferred-svg-render* :hiccup)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def hiccup (binary-stl-file-&gt;svg "resources/isle_of_man.stl")))
20-05-25 09:37:44 mason INFO [walkmap.svg:82] - Generating SVG for :hiccup renderer
"Elapsed time: 52.614707 msecs"
#'walkmap.svg/hiccup
walkmap.svg=&gt; (def ^:dynamic *preferred-svg-render* :dali)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def dali (binary-stl-file-&gt;svg "resources/isle_of_man.stl")))
20-05-25 09:38:07 mason INFO [walkmap.svg:82] - Generating SVG for :dali renderer
"Elapsed time: 49.891043 msecs"
#'walkmap.svg/dali
</code></pre>
<p>This implies that the problem is not in the way polygons are formatted.</p>
<p>The difference between the two versions of <code>facet-&gt;svg-poly</code> is as follows:</p>
<h3><a href="#new-version-works-with-both-hiccup-and-dali-" name="new-version-works-with-both-hiccup-and-dali-"></a>New version, works with both Hiccup and Dali:</h3>
<pre><code>walkmap.svg=&gt; (def stl (decode-binary-stl "resources/isle_of_man.stl"))
#'walkmap.svg/stl
walkmap.svg=&gt; (def facet (first (:facets stl)))
#'walkmap.svg/facet
walkmap.svg=&gt; (pprint facet)
{:normal {:x -0.0, :y 0.0, :z 1.0},
:vertices
[{:x 3.0, :y 1.0, :z 1.0}
{:x 2.0, :y 3.0, :z 1.0}
{:x 0.0, :y 0.0, :z 1.0}],
:abc 0}
nil
walkmap.svg=&gt; (pprint (facet-&gt;svg-poly facet))
[:polygon {:points "3.0,1.0 2.0,3.0 0.0,0.0"}]
nil
</code></pre>
<p>In other words, the new version constructs the <code>:points</code> attribute of the <code>:polygon</code> tag by string concatenation, and the renderer just needs to output it.</p>
<h3><a href="#older-version-works-with-dali-only-" name="older-version-works-with-dali-only-"></a>Older version, works with Dali only:</h3>
<pre><code>walkmap.svg=&gt; (pprint (dali-facet-&gt;svg-poly facet))
[:polygon [3.0 1.0] [2.0 3.0] [0.0 0.0]]
nil
</code></pre>
<p>This means that the renderer is actually doing more work, since it has to compose the <code>:points</code> attribute itself; nevertheless there doesnt seem to be an increased time penalty.</p>
<h3><a href="#conclusion" name="conclusion"></a>Conclusion</h3>
<p>It doesnt seem that formatting the polygons is the issue.</p>
<h2><a href="#hypothesis-two-dali-renderer-scales-non-linearly-with-number-of-objects-drawn" name="hypothesis-two-dali-renderer-scales-non-linearly-with-number-of-objects-drawn"></a>Hypothesis two: Dali renderer scales non-linearly with number of objects drawn</h2>
<p>To test this, we need some otherwise-similar test files with different numbers of objects:</p>
<pre><code>walkmap.svg=&gt; (count (:facets stl))
4416
walkmap.svg=&gt; (def small-stl (assoc stl :facets (take 400 (:facets stl))))
#'walkmap.svg/small-stl
walkmap.svg=&gt; (count (:facets small-stl))
400
walkmap.svg=&gt; (def large-stl (decode-binary-stl "../the-great-game/resources/maps/heightmap.stl"))
#'walkmap.svg/large-stl
walkmap.svg=&gt; (count (:facets large-stl))
746585
walkmap.svg=&gt; (def ^:dynamic *preferred-svg-render* :dali)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (dali.io/render-svg (stl-&gt;svg small-stl) "dali-small.svg"))
20-05-25 10:12:25 mason INFO [walkmap.svg:92] - Generating SVG for :dali renderer
"Elapsed time: 32.55506 msecs"
nil
walkmap.svg=&gt; (def ^:dynamic *preferred-svg-render* :hiccup)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (spit "hiccup-small.svg" (hiccup.core/html (stl-&gt;svg small-stl))))
20-05-25 10:14:07 mason INFO [walkmap.svg:92] - Generating SVG for :hiccup renderer
"Elapsed time: 10.026369 msecs"
</code></pre>
<p>So we have</p>
<table>
<thead>
<tr>
<th> </th>
<th>Dali </th>
<th> </th>
<th>Hiccup </th>
<th> </th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td># of facets </td>
<td>time (msecs) </td>
<td>objets/msec </td>
<td>time (msecs) </td>
<td>objets/msec </td>
<td>ratio (Dali/Hiccup) </td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td>400 </td>
<td>32.55506 </td>
<td>12.29 </td>
<td>10.026369 </td>
<td>39.89 </td>
<td>3.35 </td>
</tr>
<tr>
<td>4416 </td>
<td>874.292007 </td>
<td>5.05 </td>
<td>84.09972 </td>
<td>52.51 </td>
<td>10.40 </td>
</tr>
<tr>
<td>746585 </td>
<td>29,695,695.61 </td>
<td>0.03 </td>
<td>16724.848222 </td>
<td>44.64 </td>
<td>1775.54 </td>
</tr>
</tbody>
</table>
<h3><a href="#conclusion" name="conclusion"></a>Conclusion</h3>
<p>What were seeing is that Hiccup renders more or less linearly by the number of objects (bear in mind that all of these objects are triangles, so essentially equally complex to render), whereas trhe performance of Dali degrades significantly as the number of objects increases.</p></div></div></div></body></html>