<font face="verdana,sans-serif">The situation I encounted this is doing a batch update of a map. Is there an easy way to do that? I&#39;m doing something like adding 20-or-so elements to an existing map of a few thousand.<br>

</font><br><div class="gmail_quote">On Thu, Feb 23, 2012 at 10:13 PM, wren ng thornton <span dir="ltr">&lt;<a href="mailto:wren@freegeek.org">wren@freegeek.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im">On 2/23/12 9:16 PM, Clark Gaebel wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Looking at IntMap&#39;s left-biased &#39;union&#39; function [1], I noticed that the<br>
complexity is O(n+m) where n is the size of the left map, and m is the size<br>
of the right map.<br>
<br>
Since insertion [2] is O(min(n, W)) [ where W is the number of bits in an<br>
Int ], wouldn&#39;t it be more efficient to just fold &#39;insert&#39; over one of the<br>
lists for a complexity of O(m*min(n, W))? This would degrade into O(m) in<br>
the worst case, as opposed to the current O(n+m).<br>
</blockquote>
<br></div>
The important things to bear in mind here are (1) the constant factors actually matter in practice, and (2) what&#39;s actually going on. While O(min(n,W)) is correct, it&#39;s incorrect to think about it as just a constant (or as just a linear function). While technically incorrect, it&#39;s better to think of it as O(log n) in order to get an intuition for how it works. And O(m+n) is much nicer than O(m*log n).<br>


<br>
Doing a fold with insert means that we must pay for the cost of traversing one of the maps entirely, and the cost of walking the spine for a lookup/insert m times. Whereas, with the merge function we only have to traverse the portions of the spines which intersect, and we only have to do it in one pass. In doing the fold, we&#39;re essentially ignoring the fact that the maps have a trie structure, since we have to traverse from the top for every insert; whereas for the merge, we make use of the structure in order to avoid redundant traversals of the top part of the structure.<br>


<br>
Thus, the merge is doing less work. So, in theory, it should be faster. However, again, the thing to beware of is the constant factors. In particular, big-O algorithmic analysis doesn&#39;t really account for things like locality and cache coherence, so one should always be on the lookout for places where duplicating work is actually faster in practice. If you&#39;re curious, you can always implement your own union using the fold-with-insert method and then run some benchmarks.<span class="HOEnZb"><font color="#888888"><br>


<br>
-- <br>
Live well,<br>
~wren<br>
<br>
______________________________<u></u>_________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/haskell-cafe</a><br>
<br>
</font></span></blockquote></div><br>