@@ -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