[
https://issues.apache.org/jira/browse/CASSANDRA-8915?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14523745#comment-14523745
]
Benedict commented on CASSANDRA-8915:
-------------------------------------
First off, I agree that the MergeIteratorAllEqual is unfortunately complex,
though I haven't yet attempted to fully reason about its behaviour. Are we
certain there's no way to reduce its complexity? If you don't think it can be
improved complexity-wise from its current position, I'll find some time to chew
on it myself as well, so we have at least had two distinct attempts to reduce
that burden.
However from a performance point of view, I have two major quibbles:
* There is a simple optimisation of AllEqual, which I have introduced, and it
is now universally faster (or as fast)
* I don't _think_ that's the best characterisation of LCS (please feel free to
prove me wrong, though, as I may have a poor mental model of LCS)
My optimisation as stands is actually pretty rubbish; it could be done much
better. What I do is construct a new heap from the equal candidates, and then
push down the top element and bubble up the remainder. All this does really is
compress the equal items, push down the one most likely to stay at the head,
and expand the remainder from the smallest item upwards so minimizing the
number of swaps. We could instead perform a merge, but even with this imperfect
implementation the result is typically half as many comparisons as NoEqual, and
never more.
As to LCS: to my knowledge, it only ever compacts two levels together, but
within each level there is no compaction/comparison, they are simply
concatenated together. Between the levels there's no guarantee of overlap, and
the values will typically be randomly distributed since we default to hashed
partitioning. Given each level is 10 times larger than the previous, we can
also expect that the number of _runs_ of equality are very low. I've introduced
simulation of varying numbers of levels being compacted together, along with
varying numbers of L0 sstables in the mix, and with varying levels of overlap
between the levels (100%, 50%, 0%; here I mean percentage of values in a level
which definitely occur in a lower level). These all come out as either the same
or faster under both versions of AllEqual.
Of course the statement likely stands for a variety of workloads with many CQL
row overwrites, so catering for the case of many runs of overlaps is still an
important one.
bq. but please do not hesitate to disagree or bring other
concerns/questions/scenarios to the discussion.
ditto :)
> Improve MergeIterator performance
> ---------------------------------
>
> Key: CASSANDRA-8915
> URL: https://issues.apache.org/jira/browse/CASSANDRA-8915
> Project: Cassandra
> Issue Type: Improvement
> Reporter: Branimir Lambov
> Assignee: Branimir Lambov
> Priority: Minor
> Fix For: 3.x
>
>
> The implementation of {{MergeIterator}} uses a priority queue and applies a
> pair of {{poll}}+{{add}} operations for every item in the resulting sequence.
> This is quite inefficient as {{poll}} necessarily applies at least {{log N}}
> comparisons (up to {{2log N}}), and {{add}} often requires another {{log N}},
> for example in the case where the inputs largely don't overlap (where {{N}}
> is the number of iterators being merged).
> This can easily be replaced with a simple custom structure that can perform
> replacement of the top of the queue in a single step, which will very often
> complete after a couple of comparisons and in the worst case scenarios will
> match the complexity of the current implementation.
> This should significantly improve merge performance for iterators with
> limited overlap (e.g. levelled compaction).
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)