diff --git a/Bench.cpp b/Bench.cpp index 80a38f4..5e8bf87 100644 --- a/Bench.cpp +++ b/Bench.cpp @@ -8,7 +8,7 @@ void monotonicallyIncreasing() { ankerl::nanobench::Bench bench; Facade facade{kWindow + 1}; - bench.minEpochIterations(kWindow * 10); + bench.minEpochIterations(kWindow * 20); bench.warmup(kWindow).run("monotonically increasing", [&] { const int64_t remove = __builtin_bswap64(facade.getVersion() - kWindow); @@ -106,4 +106,4 @@ void bulkFirstGeq() { int main() { monotonicallyIncreasing(); bulkFirstGeq(); -} \ No newline at end of file +} diff --git a/README.md b/README.md index f11c14d..4601b11 100644 --- a/README.md +++ b/README.md @@ -22,28 +22,29 @@ feature | weaselab | fdb | # benchmarks ## weaselab + | ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- -| 1,538.88 | 649,824.01 | 2.7% | 0.22 | `monotonically increasing` -| 1.25 | 798,888,023.37 | 0.0% | 0.01 | `*iter` -| 32.10 | 31,153,434.23 | 0.7% | 0.01 | `++iter` -| 31.08 | 32,178,831.30 | 0.3% | 0.01 | `--iter` -| 139.19 | 7,184,433.93 | 2.2% | 0.02 | `begin` -| 176.43 | 5,667,847.59 | 0.3% | 0.02 | `begin (firstGeq)` -| 54.56 | 18,329,336.92 | 0.4% | 0.01 | `end` -| 159.37 | 6,274,892.80 | 0.1% | 0.10 | `bulkFirstGeq` -| 153.55 | 6,512,408.74 | 0.1% | 0.09 | `bulkFirstGeq (latest version)` +| 1,225.88 | 815,738.46 | 0.7% | 0.31 | `monotonically increasing` +| 1.27 | 785,633,468.91 | 0.2% | 0.01 | `*iter` +| 29.18 | 34,265,322.00 | 0.4% | 0.01 | `++iter` +| 30.55 | 32,729,535.46 | 0.6% | 0.01 | `--iter` +| 155.38 | 6,435,768.30 | 0.4% | 0.04 | `begin` +| 181.88 | 5,498,125.78 | 0.5% | 0.04 | `begin (firstGeq)` +| 46.29 | 21,603,059.16 | 0.3% | 0.01 | `end` +| 169.68 | 5,893,481.63 | 0.1% | 0.10 | `bulkFirstGeq` +| 162.61 | 6,149,704.63 | 0.1% | 0.10 | `bulkFirstGeq (latest version)` ## fdb | ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- -| 2,236.83 | 447,061.26 | 1.0% | 0.29 | `monotonically increasing` -| 2.11 | 473,370,596.42 | 0.9% | 0.01 | `*iter` -| 12.07 | 82,858,977.78 | 1.2% | 0.01 | `++iter` -| 8.54 | 117,158,071.80 | 0.9% | 0.01 | `--iter` -| 94.26 | 10,608,588.66 | 1.1% | 0.01 | `begin` -| 159.01 | 6,288,940.61 | 0.4% | 0.02 | `begin (firstGeq)` -| 73.47 | 13,610,276.41 | 0.9% | 0.01 | `end` -| 422.53 | 2,366,723.10 | 0.1% | 0.25 | `bulkFirstGeq` -| 365.13 | 2,738,758.86 | 0.1% | 0.22 | `bulkFirstGeq (latest version)` +| 2,237.52 | 446,923.66 | 0.6% | 0.56 | `monotonically increasing` +| 2.07 | 484,208,685.89 | 0.6% | 0.01 | `*iter` +| 9.91 | 100,926,329.70 | 0.5% | 0.01 | `++iter` +| 11.36 | 88,023,104.91 | 0.3% | 0.01 | `--iter` +| 87.70 | 11,402,839.76 | 0.2% | 0.02 | `begin` +| 110.58 | 9,043,264.46 | 0.2% | 0.03 | `begin (firstGeq)` +| 67.30 | 14,859,247.22 | 0.3% | 0.02 | `end` +| 411.72 | 2,428,853.18 | 0.1% | 0.25 | `bulkFirstGeq` +| 350.54 | 2,852,725.55 | 0.1% | 0.21 | `bulkFirstGeq (latest version)` diff --git a/VersionedMap.cpp b/VersionedMap.cpp index 387b462..3bd04af 100644 --- a/VersionedMap.cpp +++ b/VersionedMap.cpp @@ -801,7 +801,19 @@ struct __attribute__((__visibility__("hidden"))) VersionedMap::Impl { void printInOrderHelper(int64_t version, uint32_t node, int depth); + int accumulatedFuel = 0; + void scanAndRemoveOldEntries(int fuel) { + accumulatedFuel += fuel; +#ifdef NDEBUG + // This is here for performance reasons, since we want to amortize the cost + // of searching for continueKey. In tests, we want to exercise the rest of + // the code often. + if (accumulatedFuel < 500) { + return; + } +#endif + // Get a finger to the first entry > continueKey, or the last entry if // continueKey is the empty string if (latestRoot == 0) { @@ -838,7 +850,7 @@ struct __attribute__((__visibility__("hidden"))) VersionedMap::Impl { // Phew. Ok now we have a finger to the next entry to consider removing, and // the range version terminated at this entry. - for (; fuel > 0; --fuel) { + for (; accumulatedFuel > 0; --accumulatedFuel) { const auto &n = mm.base[finger.backNode()]; if (rangeVersion < 0 && std::max(n.entry->pointVersion, n.entry->rangeVersion) < oldestVersion) {