Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The first question is: what constitutes a "one-pass" algorithm? Something that could naturally be implemented as a single top-down loop would qualify. In contrast, recursion--compiled naively--normally has two passes, one on the way down and one on the way back up. <em>Tail recursion</em> can easily be compiled into a loop, and usually is in functional languages. <em><a href="http://en.wikipedia.org/wiki/Tail_call#Tail_recursion_modulo_cons" rel="nofollow noreferrer">Tail recursion modulo cons</a></em> is a similar, albeit less common, optimization. But, even if your compiler doesn't support tail recursion modulo cons, you can easily convert such an implementation into a loop by hand.</p> <p>Tail recursion modulo cons is similar to ordinary tail recursion, except that the tail call is wrapped in a constructor, which can be allocated and partially filled in before the recursive call. In this case, you would want the return expressions to be something like <code>T (1+size(a)+size(b)+size(c),x,a,merge(b,c))</code>. The key insight required here (as mentioned in the edit on the <a href="https://stackoverflow.com/questions/3526117/weight-biased-leftist-heaps-advantages-of-top-down-version-of-merge">other SO thread</a>) is that you don't need to perform the merge to know how big the result it is going to be, and therefore which side of the new tree it should go on. This is because the size of <code>merge(b,c)</code> will always be <code>size(b)+size(c)</code>, which can be calculated outside the merge. </p> <p>Notice that the original <code>rank</code> function for ordinary leftist heaps does <em>not</em> share this property, and so cannot be optimized in this fashion.</p> <p>Essentially, then, you inline the two calls to makeT <em>and also</em> convert the calls of the form <code>size(merge(b,c))</code> to <code>size(b)+size(c)</code>.</p> <p>Once you make this change, the resulting function is significantly lazier than the original, because it can return the root of the result <em>before</em> evaluating the recursive merge.</p> <p>Similarly, in a concurrent environment involving locks and mutation, the new implementation could support significantly more concurrency by acquiring and releasing locks for each node along the way, rather than locking the entire tree. (Of course, this would only make sense for very lightweight locks.)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload