Make Prio queues more compact#118
Conversation
5e6790d to
87bdf15
Compare
|
@konsumlamm This is obviously not quite ready to actually merge, but before I make it so, I was hoping you'd give it a glance and see if it's something you'd be okay with if indeed it improves performance. |
c2df822 to
88c8c90
Compare
|
Note: along with reducing the total queue size by |
|
@konsumlamm I believe this is ready to go. |
e77449e to
11e01c4
Compare
|
I guess there's still the question of whether to let maps be lazy (better for performance in general) or whether to make them stricter (maintaining theoretical worst-case bounds). I'd lean toward the former in this instance, but I hate having to decide. |
|
@konsumlamm, this still awaits your comments. |
|
@konsumlamm It's been two weeks now. |
konsumlamm
left a comment
There was a problem hiding this comment.
Sorry for taking so long to review, this is not a simple PR.
I find the Nattish approach a bit confusing, but the numbers speak for themselves. I'm actually surprised that the benchmarks improve so much though, all that really changed is Zero, isn't it? I'd expect data Zero k a = Zero to be a single global value, so why does this make such a big difference?
Did you benchmark the folds? They look like they might get slower with this change.
|
I don't remember the numbers I got from benchmarks. What did they look like to you? The space savings aren't in the |
The benchmarks take 10-20% less time for me.
I see, so we save one word per tree. This is |
|
Ok, the folds seem to improve as well. |
Incorrect. You can count out the |
Ah right, the |
You mean lazy in the spine? What is the current situation? Does this PR change that? |
|
What were off were my allocation calculations, which I believe I overstated. I'll have to recalculate those if anyone cares. |
|
Lazy all through. If we want to be strict instead, I can do that, but the code will be more complicated and for the most part I expect slower. |
|
Well ... for now it keeps the plain (non- |
|
I don't like having different laziness for Can you explain why the new representation necessitates fully lazy maps? Why can't we just keep the old implementation? I'm a bit worried that fully lazy maps might lead to situations where you build up a lot of computations which slow down a subsequent |
|
It doesn't necessitate fully lazy maps. Keeping them strict in the spine is easy, but not very useful for predictable performance. Keeping them entirely strict in the structure is quite possible too, but it's slightly trickier. That said, I just realized it should be somewhat less tricky with the |
So why was that useful before, but not anymore? |
|
The old representation had entirely strict trees, which held lazy values, so calculating the spine strictly calculated everything (except the values) strictly. The new representation uses the same fields for values as for lists of trees, so those fields must be lazy. To calculate everything but the values strictly, we must calculate strictly down to |
Store the value associated with each key as its rightmost child, which saves one word per element. As a result, the binomial trees must become lazy, which should be good for maps and lazy traversals. The down side is that we will need tag checks to know that we have realized `Succ` constructors. Benchmarking suggests this implementation is substantially faster than the previous one.
* Make maps and unordered traversals build the structure eagerly again, and restore the key strictness of `mapKeysMonotonic`. * Fix the documentation of `mapKeysMonotonic`. The given function need only be weakly monotonic; strict monotonicity is not required.
We no longer require the function to be *strictly* monotonic, so we should test with weakly monotonic functions.
|
@konsumlamm I think maps should be back to the way they were now. |
Document `mapU` and strengthen its test.
|
Sorry, I double confused myself. The allocation reduction is as big as I thought. |
Store the value associated with each key as its rightmost child,
which saves one word per element.
As a result, the binomial trees must become lazy, which should be
good for maps and lazy traversals. The down side is that we will
need tag checks to know that we have realized
Succconstructors.Benchmarks indicate this improves performance.
Closes #115.