[llvm-exegesis] Clustering: don't enqueue a point multiple times
authorFangrui Song <maskray@google.com>
Sun, 23 Dec 2018 20:48:52 +0000 (20:48 +0000)
committerFangrui Song <maskray@google.com>
Sun, 23 Dec 2018 20:48:52 +0000 (20:48 +0000)
commitcd93d7ef439c9fd48aeb7e8a20311bb2ff1950d9
tree71942a9d6cafed773d6507e118f2c2e1c5ffa397
parent93f1074677edb685ae11e154dbe81b7130a0c226
[llvm-exegesis] Clustering: don't enqueue a point multiple times

Summary:
SetVector uses both DenseSet and vector, which is time/memory inefficient. The points are represented as natural numbers so we can replace the DenseSet part by indexing into a vector<char> instead.

Don't cargo cult the pseudocode on the wikipedia DBSCAN page. This is a standard BFS style algorithm (the similar loops have been used several times in other LLVM components): every point is processed at most once, thus the queue has at most NumPoints elements. We represent it with a vector and allocate it outside of the loop to avoid allocation in the loop body.

We check `Processed[P]` to avoid enqueueing a point more than once, which also nicely saves us a `ClusterIdForPoint_[Q].isUndef()` check.

Many people hate the oneshot abstraction but some favor it, therefore we make a compromise, use a lambda to abstract away the neighbor adding process.

Delete the comment `assert(Neighbors.capacity() == (Points_.size() - 1));` as it is wrong.

llvm-svn: 350035
llvm/tools/llvm-exegesis/lib/Clustering.cpp