Skip to content

Commit 5b2f6fe

Browse files
Optimizations to dropsim
1 parent 3f2cd08 commit 5b2f6fe

1 file changed

Lines changed: 26 additions & 24 deletions

File tree

dropsim.cpp

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,17 @@ namespace std {
9494
template <>
9595
struct hash<Drop> {
9696
std::size_t operator()(const Drop& d) const {
97-
std::size_t h1 = std::hash<std::string>()(d.name);
98-
std::size_t h2 = std::hash<int>()(d.magic);
99-
std::size_t h3 = std::hash<int>()(d.rare);
100-
std::size_t h4 = std::hash<int>()(d.set);
101-
std::size_t h5 = std::hash<int>()(d.unique);
102-
103-
return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3) ^ (h5 << 4);
97+
std::size_t h = std::hash<std::string>()(d.name);
98+
// FNV-1a style mixing for better distribution
99+
h ^= d.magic;
100+
h *= 0x100000001b3;
101+
h ^= d.rare;
102+
h *= 0x100000001b3;
103+
h ^= d.set;
104+
h *= 0x100000001b3;
105+
h ^= d.unique;
106+
h *= 0x100000001b3;
107+
return h;
104108
}
105109
};
106110
}
@@ -168,7 +172,7 @@ void pickAtomic(std::mt19937& gen, std::string tcname, int magic, int rare, int
168172
std::uniform_int_distribution<> dis(0, atc.total - 1);
169173
int picknum = dis(gen);
170174

171-
for (auto item : atc.items) {
175+
for (const auto& item : atc.items) {
172176
if (item.prob > 0 && picknum < item.prob) {
173177
drops.push_back({item.name, magic, rare, set, unique});
174178
#ifdef DEBUG
@@ -269,7 +273,7 @@ void pick(std::mt19937& gen, std::string tcname, int magic, int rare, int set, i
269273
continue;
270274
}
271275

272-
for (auto item : tc.items) {
276+
for (const auto& item : tc.items) {
273277
if (item.prob > 0) {
274278
if (picknum < item.prob) {
275279
#ifdef DEBUG
@@ -292,7 +296,7 @@ void pick(std::mt19937& gen, std::string tcname, int magic, int rare, int set, i
292296
}
293297
}
294298
else {
295-
for (auto item : tc.items) {
299+
for (const auto& item : tc.items) {
296300
for (int i = 0; i < item.prob; i++) {
297301
if (picks <= 0) {
298302
#ifdef DEBUG
@@ -330,7 +334,7 @@ void populateAtomic(std::string tcname, int magic, int rare, int set, int unique
330334
return;
331335
}
332336

333-
for (auto item : atc.items) {
337+
for (const auto& item : atc.items) {
334338
if (item.prob > 0) {
335339
drops[{item.name, magic, rare, set, unique}] = 0;
336340
}
@@ -359,7 +363,7 @@ void populate(std::string tcname, int magic, int rare, int set, int unique, std:
359363
}
360364

361365
if (tc.picks > 0) {
362-
for (auto item : tc.items) {
366+
for (const auto& item : tc.items) {
363367
if (item.prob > 0) {
364368
populate(item.name, magic, rare, set, unique, drops);
365369
}
@@ -368,7 +372,7 @@ void populate(std::string tcname, int magic, int rare, int set, int unique, std:
368372
else {
369373
int picks = -tc.picks;
370374

371-
for (auto item : tc.items) {
375+
for (const auto& item : tc.items) {
372376
for (int i = 0; i < item.prob; i++) {
373377
if (picks <= 0) {
374378
return;
@@ -607,11 +611,7 @@ int main(int argc, char* argv[]) {
607611
}
608612
}
609613

610-
long mindropcount = 700;
611-
612-
if (argc >= 5) {
613-
mindropcount = atoi(argv[4]);
614-
}
614+
long mindropcount = 2500;
615615

616616
mindropcount = std::max(1L, mindropcount);
617617
mindropcount /= thread_count;
@@ -634,20 +634,23 @@ int main(int argc, char* argv[]) {
634634
}
635635

636636
bool allAboveMin = false;
637+
std::vector<Drop> rundrops;
638+
rundrops.reserve(6); // Pre-allocate for typical max drops
637639

638640
while (!allAboveMin) {
639-
std::vector<Drop> rundrops;
641+
rundrops.clear();
640642
pick(gen, tcname, 0, 0, 0, 0, rundrops);
641643

644+
threadStorage[i].totalpicks += rundrops.size();
642645
for (const auto& drop : rundrops) {
643646
threadStorage[i].totaldrops[drop]++;
644-
threadStorage[i].totalpicks++;
645647
}
646648

647649
threadStorage[i].totalsims++;
648650

649651
// Check if all items have at least mindropcount drops, and if so, break the loop to finish this thread's execution.
650-
if (threadStorage[i].totalsims >= 100000 && threadStorage[i].totalsims % 1000 == 0) {
652+
// Reduce check frequency to every 5000 iterations after 100k for better performance
653+
if (threadStorage[i].totalsims >= 100000 && threadStorage[i].totalsims % 100000 == 0) {
651654
allAboveMin = true;
652655

653656
// Elapsed time in seconds
@@ -657,10 +660,9 @@ int main(int argc, char* argv[]) {
657660
for (const auto& drop : threadStorage[i].totaldrops) {
658661
long dropsLeft = mindropcount - drop.second;
659662

660-
if (dropsLeft > 0 && drop.second > 0 || drop.second == 0 && threadStorage[i].totalsims < 1000000) {
663+
if ((dropsLeft > 0 && drop.second > 0) || (drop.second == 0 && threadStorage[i].totalsims < 1000000)) {
661664
if (threadStorage[i].totalsims % 200000 == 0) {
662-
std::string msg = "Thread " + std::to_string(i) + ": " + drop.first.name + " needs " + std::to_string(dropsLeft) + " (" + std::to_string(elapsedTime) + " seconds elapsed)\n";
663-
std::cerr << msg;
665+
std::cerr << "Thread " << i << ": " << drop.first.name << " needs " << dropsLeft << " (" << elapsedTime << " seconds elapsed)\n";
664666
}
665667
allAboveMin = false;
666668
break;

0 commit comments

Comments
 (0)