NICON Posted December 27, 2018 Share Posted December 27, 2018 I have a while loop in a script that is running for a very long time due to the large values that are passing through it. Below is the link to the pastebin code and code embedded in this forum. Loop Statement Snipet if (!$user_class->invincible) { if (!$defender->invincible) { while ($yourhp > 0 && $theirhp > 0) { $damage = round($defender->moddedstrength) - $user_class->moddeddefense; $damage = ($damage < 1) ? 1 : $damage; if (!$wait) { $yourhp = $yourhp - $damage; ++$number; $log[] = $number . ": " . $defender->formattedname . " hit you for " . prettynum($damage) . " damage using their " . $defender->weaponname . ". <br />"; } else $wait = 0; if ($yourhp > 0) { $damage = round($user_class->moddedstrength) - $defender->moddeddefense; $damage = ($damage < 1) ? 1 : $damage; $theirhp = $theirhp - $damage; ++$number; $log[] = $number . ": " . "You hit " . $defender->formattedname . " for " . prettynum($damage) . " damage using your " . $user_class->weaponname . ". <br />"; } } $log = array_slice($log, -10, 10, true); foreach($log as $text) echo $text; } else $yourhp = 0; } else $theirhp = 0; My issue is that $yourhp and $theirhp can be in the 100's of thousands causing this to loop half a million plus times. I was curious if there was a way to only show the first few lines and last few lines of this but still retain the increment value that's created? Thanks so much in advance. NICON Quote Link to comment Share on other sites More sharing options...
requinix Posted December 28, 2018 Share Posted December 28, 2018 Even 10,000,000 times through the loop should execute in a split second. How long as we talking? What if you remove the $log? And what version of PHP? Quote Link to comment Share on other sites More sharing options...
NICON Posted December 28, 2018 Author Share Posted December 28, 2018 14 hours ago, requinix said: Even 10,000,000 times through the loop should execute in a split second. How long as we talking? What if you remove the $log? And what version of PHP? The current version running on the server is 5.5.9. It executes for roughly 30 to 40 seconds then gives an error screen. If I remove the $log in the while loop it does execute properly. Just wont give any output on the screen as to the results of this section of code. Quote Link to comment Share on other sites More sharing options...
NICON Posted December 28, 2018 Author Share Posted December 28, 2018 Should I toss in an if statement limiting the output from the $log to the first few and last loop? Quote Link to comment Share on other sites More sharing options...
NICON Posted December 28, 2018 Author Share Posted December 28, 2018 if ($number <= 9 || $yourhp <= 0) { $log[] = $number . ": " . $defender->formattedname . " hit you for " . prettynum($damage) . " damage using their " . $defender->weaponname . ". <br />"; } if ($number <= 9 || $theirhp <= 0) { $log[] = $number . ": " . $defender->formattedname . " hit you for " . prettynum($damage) . " damage using their " . $defender->weaponname . ". <br />"; } Adding these 2 if statements in limits the amount of data stored in the array... Which may have been the issue all along just way to much info in the array? I was getting a 500 error because of it. Quote Link to comment Share on other sites More sharing options...
requinix Posted December 29, 2018 Share Posted December 29, 2018 Appending lots of entries to an array can hurt performance, especially in old versions of PHP. You don't even need a loop for all this anyways: the damage dealt is constant so with some simple math you can calculate exactly (a) how many rounds it would take and (b) the final health values for both sides. if (!$user_class->invincible && !defender->invincible) { $yourdamage = max(1, round($user_class->moddedstrength) - $defender->moddeddefense); $theirdamage = max(1, round($defender->moddedstrength) - $user_class->moddeddefense); $yourrounds = ceil($theirhp / $yourdamage); $theirrounds = ceil($yourhp / $theirdamage); $rounds = min($yourrounds, $theirrounds); $yourhp = $yourhp - $theirdamage * $rounds; $theirhp = $theirhp - $yourdamage * $rounds; // ... } else if ($user_class->invincible) { $theirhp = 0; } else { $yourhp = 0; } Two parts left: constructing the logs you want to show and adjusting for $wait. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.