Skip to content

Commit 8b2be07

Browse files
committed
Binary search rather than sequential search
1 parent b812be1 commit 8b2be07

File tree

1 file changed

+18
-21
lines changed

1 file changed

+18
-21
lines changed

src/litterer.cpp

+18-21
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <litterer/litterer.h>
2+
#include <numeric>
23

34
#if _WIN32
45
#ifndef NOMINMAX
@@ -49,6 +50,12 @@ void partial_shuffle(std::vector<T>& v, std::size_t n, Generator& g) {
4950
std::swap(v[i], v[j]);
5051
}
5152
}
53+
54+
std::vector<size_t> cumulative_sum(const std::vector<size_t>& bins) {
55+
std::vector<size_t> cumsum(bins.size());
56+
std::partial_sum(bins.begin(), bins.end(), cumsum.begin());
57+
return cumsum;
58+
}
5259
} // namespace
5360

5461
void runLitterer() {
@@ -112,8 +119,9 @@ void runLitterer() {
112119
const std::string mallocSourceObject = mallocInfo.dli_fname;
113120
#endif
114121

115-
const std::size_t nAllocations = data["NAllocations"].get<std::size_t>();
116-
const std::size_t maxLiveAllocations = data["MaxLiveAllocations"].get<std::size_t>();
122+
const auto bins = data["Bins"].get<std::vector<std::size_t>>();
123+
const auto nAllocations = data["NAllocations"].get<std::size_t>();
124+
const auto maxLiveAllocations = data["MaxLiveAllocations"].get<std::size_t>();
117125
const std::size_t nAllocationsLitter = maxLiveAllocations * multiplier;
118126

119127
fprintf(log, "==================================== Litterer ====================================\n");
@@ -126,32 +134,21 @@ void runLitterer() {
126134
fprintf(log, "timestamp : %s %s\n", __DATE__, __TIME__);
127135
fprintf(log, "==================================================================================\n");
128136

129-
assertOrExit(
130-
[&] {
131-
std::size_t sum = 0;
132-
for (const auto& bin : data["Bins"]) {
133-
sum += bin.get<std::size_t>();
134-
}
135-
return sum;
136-
}() == nAllocations,
137-
log, "The sum of all bins should equal nAllocations.");
137+
assert(std::accumulate(bins.begin(), bins.end(), 0zu) == nAllocations);
138+
const std::vector<std::size_t> binsCumSum = cumulative_sum(bins);
138139

139140
const auto litterStart = std::chrono::high_resolution_clock::now();
140141

141-
std::uniform_int_distribution<std::size_t> distribution(0, nAllocations - 1);
142+
std::uniform_int_distribution<std::int64_t> distribution(1, nAllocations);
142143
std::vector<void*> objects = *(new std::vector<void*>);
143144
objects.reserve(nAllocationsLitter);
144145

145146
for (std::size_t i = 0; i < nAllocationsLitter; ++i) {
146-
std::size_t allocationSize = 1;
147-
std::int64_t offset = static_cast<int64_t>(distribution(generator)) - data["Bins"][0].get<std::size_t>();
148-
149-
while (offset >= 0) {
150-
++allocationSize;
151-
offset -= static_cast<std::size_t>(data["Bins"][allocationSize - 1].get<std::size_t>());
152-
}
153-
154-
void* pointer = MALLOC(allocationSize);
147+
const auto offset = distribution(generator);
148+
const auto it = std::lower_bound(binsCumSum.begin(), binsCumSum.end(), offset);
149+
assert(it != binsCumSum.end());
150+
const auto bin = std::distance(binsCumSum.begin(), it) + 1;
151+
void* pointer = MALLOC(bin);
155152
objects.push_back(pointer);
156153
}
157154

0 commit comments

Comments
 (0)