This is not a question about principles or common coding procedures, it is a question about how PHP processes code, or more precisely, doesn't process code that it should ignore, in the name of better understanding how PHP works
Scenario 1:
if (1==2) { echo rand(0,99); }
Obviously, the code above will not have any output, and that's not what the question is about; but rather, about whether or not PHP even considers making any output. As PHP goes through the page, does it entirely skip the code assigned to the failed if-check, or does it get allocated any sort of resources beyond simply what the filesize does?
Scenario 2:
if (1==2) { for ($x = 0; $x <= 999999; $x++) { echo rand(0,99); } }
Similar to scenario 1 but with a key difference to clarify the point, considering that 1==2 is always going to be false, does this code use any more resources than the previous one or will they both be equally "cheap" to process? Or are there any "hidden" actions that add up even if the code in the loop is as minimal as this?
Scenario 3:
for ($x = 0; $x <= 999999; $x++) { if (1==2) { echo rand(0,99); } }
Now, this one should see a false statement a million times, but how significant is that really in terms of resources? Will it keep checking if 1 is 2 or does PHP "learn" from the first time it checks? And does it spend any resources beyond that, or is a simple if-check like this inside a loop the only thing PHP will process? Will it "read" echo rand(0,99); a million times, even though 1 is not 2?
Scenario 4:
for ($x = 0; $x <= 999999; $x++) { if (1==2) { for ($x = 0; $x <= 999999; $x++) { echo rand(0,99); } } }
Finally, a combination of them all, will this example be a massive loop-in-a-loop-level of resource wasting or will the inner loop be completely ignored from processing? In other words, will 1!=2 cause PHP to entirely skip processing the inner loop, or will it waste memory on code that it should ignore? And how different is this scenario compared to the previous three in terms of processing and resources?
Thanks in advance for any PHP and memory-usage expertise on the matter, it is my hope that the answer to this question will bring better understanding about how PHP processes code to me and others
EDIT:
Another somewhat relevant example would be that of having a large amount of comments within a loop compared to outside of it; would comments inside of a loop affect performance differently in any way (regardless of how "unnoticeable" you might consider it to be) than the same amount of comments outside of the loop?
1 & 2) Everything inside these if blocks is not evaluated
3) PHP doesnt learn anything, it will perform 1 million if checks. This isn't significant but it's not insignificant either. As one commenter suggested, try it and see the page time hit.
4) This generates the same amount of processing as #3
Related
I have spent some time trying to execute the Fibonacci sequence to 500 numbers and output to screen in the shortest amount of code possible. This was a learning exercise for me.
I have condensed it from 21 lines down to 12, this is the shortest code I can write that makes this work.. Can anyone show me how I could have made the code even shorter?
I have looked on google for PHP loops, and the while loop seemed to work best.
Are there any other math tricks in PHP I can use to condense this even more?
Normally when I ask a question, I like to show what research I have done into the problem, but since I don't know any keywords to look up for better math or loops, I am not sure what to search..
Code:
$counter = 0;
$first = 1;
$second = 1;
echo $first."<br/>";
echo $second."<br/>";
while ($counter < 500) {
$next = $first + $second;
echo $next."<br/>";
$counter++;
$second=$first;
$first=$next;
}
The research for the shortest code is called "code golf" and there is a whole stack exchange site devoted to it.
In particular, your question is answered here.
The code is:
<?for($a=$b++;;$b+=$a=$b-$a){echo$a;}
this works by:
removing whitespaces (which are ignored anyway) (cosmetic)
giving variables meaningless names (doesn't affect the output)(cosmetic)
abusing various language features like implicit initialization to zero and multiple assignments
the multiple assignment trick lets you use two variables instead of three (no need for the "current number") exploiting the order of the assignment
I am at a complete loss. I've searched this site extensively and others as to why my for loop, among many other working loops, will not execute, and tried many suggestions. I have checked that it is in fact not executing and not failing to meet a condition for its execution. This is the loop:
if (count($bunnyList)>100){
echo "Too many bunnies! Initiating mass cull.</br>";
for ($i=0; $i===50; $i++){
echo 'something';
unset ($bunnyList[rand(0,(count($bunnyList)))]);
array_values($bunnyList);
}
echo 'Number of bunnies: '.(count($bunnyList));
The if condition executes; the first echo statement executes, and then the echo statement following the loop also executes. If the loop had been executed, then I should get a number of "something"s printed to the page, and yet I never have, even after trying tons of suggestions for other people's failed for loops. After staring at this particular piece of code for hours I'm reasonably sure I haven't messed up a piece of syntax. Please help me, I've already pulled too many chunks of my hair ou
:(
The entire code is over a hundred lines long and I didn't think it prudent to post the whole thing. In addition, all the other for loops within the program work just fine, while endless variations of this one do not.
I apologize if this is a redundant question or if it has been asked before. Other answers to questions similar to mine were not able to fix the problem. Please help me D:
TL;DR Why does only this for loop not execute within my program containing many functioning loops? The echo statements within the if condition do execute.
Try:
for ($i = 0; $i < 50; $i++) {
Instead of:
for ($i = 0; $i === 50; $i++) {
In a for loop, the second part is NOT the ending condition, but the continuation condition. In your case it's checking if $i is equals to 50, and because it is not, it will never go in the loop.
I'm not too familiar with php, more java, but shouldn't it for each time 'I' is less than 50, increment by 1?
for ($i=0; $i < 50; $i++){
...
}
I am assuming that is the syntax.
Try like this:
for ($i=0; $i<=50; $i++){
echo 'something';
unset ($bunnyList[rand(0,(count($bunnyList)))]);
array_values($bunnyList);
}
function rec_func($x) {
echo $x;
if ($x < 1000) {
$x++;
rec_func(&$x);
}
}
This is not the actual recursive function, that I am going to be using for my PHP script. Just like this example, my real function works perfectly fine, up to the point where I start examining how much memory is it using.
If I loop this function, say, a 100 times, nothing bad happens. The used memory in each iteration stays the same. But If I loop 1000 times and more, at one point this function will start consuming more memory than before, right up to the last iteration.
The amount of spikes seem to depend on how big is the variable I give it, and how many iterations it goes through, but I can't be certain. And this is where the problem begins. This function will start consuming more memory just once in a 1000 times. My function, however, does this every 150 or so times in 1000 iterations, and the worst thing is that MY function may have to loop even more times than that.
This made me curious, because the obvious thing to do would be to use a traditional loop instead (which I have done), but I really want to understand why is this happening, and if it can be avoided.
P.S. note that I'm using a real variable only in the first iteration and all of the iterations following it are using a reference, to preserve memory. Thanks in advance.
(correct me if I am wrong).
I think, it is related with your PHP module memory handling: It does reserve some memory when it starts running (if it is used as CGI for example, or you call it from a command prompt).
Every time when you start a recursion, it will do two things basically:
Before calling the next level of recursion, saves the current status to the call stack. If you are not manipulating with references, then the variable data as well, with the current stack state. As long as the reserved memory is enough, your memory consumption will not be increased, but when you run out of memory, a new bunch of memory will be reserved, in order if more will be needed.
It means the following:
function rec_func($x) {
echo $x;
if ($x < 1000) {
$x++;
rec_func($x);
}
}
This will have a significant bigger memory usage, as every time a recursion occures, there will be an extra line in the stack, and you will create an extra $x in the memory to store it's current state, in order to reserve the value when the recursion get's back to the current stack call.
The following lines will get rid of the memory usage problem - it manipulates with variable references (obviously ruins the functionality in this case:
function rec_func(&$x) {
echo $x;
if ($x < 1000) {
$x++;
rec_func($x);
}
}
(your original code causes fatal error due to call-time reference passing).
In case if you want to reduce the memory usage, you should (or can) use references in the function declaration for variables, which will not change during the recursion, but never do that with variables, that change meanwhile.
You can try it out yourself by playing with debug_zval_dump(), like this:
<?php
function rec_func_ref(&$x) {
//echo $x;
if ($x < 100000) {
$x++;
rec_func_ref($x);
}
echo 'rec_func_ref:'.$x.'------<br />';
debug_zval_dump($x);
echo "<br />";
}
function rec_func_not_ref($x) {
//echo $x;
if ($x < 100000) {
$x++;
rec_func_not_ref($x);
}
echo 'rec_func_not_ref:'.$x.'------<br />';
debug_zval_dump($x);
echo "<br />";
}
$a = 1;
rec_func_ref($a);
$a = 1;
rec_func_not_ref($a);
?>
This question already has answers here:
Commenting interpreted code and performance
(9 answers)
Closed 9 years ago.
i have this doubt from many days. in every PHP code i write, i will write many comments, leave many white spaces and leave 4 to 5 empty lines between section and section (to make it clear for me)
will all these empty spaces, comments, empty lines make my PHP code to run slow ?
personal experiences are much appreciated :)
This is really a matter of IO and hard drive speed. If your bare file is 10KB and comments and line breaks add 4KB then the extra time that the hard drive spends reading more KB is what you need to benchmark (it's negligible by the way), not even worth your time.
If you start getting into micro-optimization then you run the risk of making your code absolutely horrid to read and maintain.
The best way to speed up your code is to re-factor code where necessary and don't do silly things that obviously hog resources like this crude example:
<?php
$arr = array(); // pretend it has 50,000 items
//GOOD IDEA: count the array once and reference that number
$arr_count = count($arr);
for($i=0; $i < $arr_count; $i++){
echo $arr[$i];
}
//BAD IDEA: re-counting the array for every iteration
for($i=0; $i < count($arr); $i++){
echo $arr[$i];
}
?>
Also unsetting a large array after you are done using it is better than waiting for the Garbage Collector to kick in. For example: pulling data from DB and looping through it. Unset the data when done and keep coding.
Comments and white space are completely ignored when the code is run. You can think of all that extra stuff as being completely wiped away once your done and the code is doing its thing.
Extra white space and comments are solely there for you and fellow coders to be better able to read and understand your code. In fact, if you don't use extra white space and comments, coders will get angry with you for writing and providing terrible code!
Consider the following code.
<?php
$time = round(microtime(true) * 1000);
for($i = 0; $i < 1000000; $i++) {
/*
*/
}
echo (round(microtime(true) * 1000) - $time) . "<br/>";
$time = round(microtime(true) * 1000);
for($i = 0; $i < 1000000; $i++) {
}
echo (round(microtime(true) * 1000) - $time) . "<br/>";
?>
There are times that the first is faster and others that the second is fast. So comments do not affect the speed.
Not really, is the simple answer for general scripts and coding.
It's likely that if you were having to consider gaining a few milliseconds here and there, and removing comments was affective, A) you have too many comments, and B) you'd already know about it all and be performing benchmarks etc.
The amount of comments is usually proportionate to the amount of code you have. ie a line or two of comments for a load of IF/ELSE, setting vars to POST or SESSIONS etc, and DB queries etc. And as the majority of PHP's time parsing a script is opening the file, accessing memory, checking thousands of things including cache etc, reading and executing the code, accessing database etc, the time taken to ignore your comments is probably .001%
Comments are used by you, and possibly other developers, to understand the code. Just keep them neat and try to keep them as short as possible while remaining concise, factual and useful.
I use often the function sizeof($var) on my web application, and I'd like to know if is better (in resources term) store this value in a new variable and use this one, or if it's better call/use every time that function; or maybe is indifferent :)
TLDR: it's better to set a variable, calling sizeof() only once. (IMO)
I ran some tests on the looping aspect of this small array:
$myArray = array("bill", "dave", "alex", "tom", "fred", "smith", "etc", "etc", "etc");
// A)
for($i=0; $i<10000; $i++) {
echo sizeof($myArray);
}
// B)
$sizeof = sizeof($myArray);
for($i=0; $i<10000; $i++) {
echo $sizeof;
}
With an array of 9 items:
A) took 0.0085 seconds
B) took 0.0049 seconds
With a array of 180 items:
A) took 0.0078 seconds
B) took 0.0043 seconds
With a array of 3600 items:
A) took 0.5-0.6 seconds
B) took 0.35-0.5 seconds
Although there isn't much of a difference, you can see that as the array grows, the difference becomes more and more. I think this has made me re-think my opinion, and say that from now on, I'll be setting the variable pre-loop.
Storing a PHP integer takes 68 bytes of memory. This is a small enough amount, that I think I'd rather worry about processing time than memory space.
In general, it is preferable to assign the result of a function you are likely to repeat to a variable.
In the example you suggested, the difference in processing code produced by this approach and the alternative (repeatedly calling the function) would be insignificant. However, where the function in question is more complex it would be better to avoid executing it repeatedly.
For example:
for($i=0; $i<10000; $i++) {
echo date('Y-m-d');
}
Executes in 0.225273 seconds on my server, while:
$date = date('Y-m-d');
for($i=0; $i<10000; $i++) {
echo $date;
}
executes in 0.134742 seconds. I know these snippets aren't quite equivalent, but you get the idea. Over many page loads by many users over many months or years, even a difference of this size can be significant. If we were to use some complex function, serious scalability issues could be introduced.
A main advantage of not assigning a return value to a variable is that you need one less line of code. In PHP, we can commonly do our assignment at the same time as invoking our function:
$sql = "SELECT...";
if(!$query = mysql_query($sql))...
...although this is sometimes discouraged for readability reasons.
In my view for the sake of consistency assigning return values to variables is broadly the better approach, even when performing simple functions.
If you are calling the function over and over, it is probably best to keep this info in a variable. That way the server doesn't have to keep processing the answer, it just looks it up. If the result is likely to change, however, it will be best to keep running the function.
Since you allocate a new variable, this will take a tiny bit more memory. But it might make your code a tiny bit more faster.
The troubles it bring, could be big. For example, if you include another file that applies the same trick, and both store the size in a var $sizeof, bad things might happen. Strange bugs, that happen when you don't expect it. Or you forget to add global $sizeof in your function.
There are so many possible bugs you introduce, for what? Since the speed gain is likely not measurable, I don't think it's worth it.
Unless you are calling this function a million times your "performance boost" will be negligible.
I do no think that it really matters. In a sense, you do not want to perform the same thing over and over again, but considering that it is sizeof(); unless it is a enormous array you should be fine either way.
I think, you should avoid constructs like:
for ($i = 0; $i < sizeof($array), $i += 1) {
// do stuff
}
For, sizeof will be executed every iteration, even though it is often not likely to change.
Whereas in constructs like this:
while(sizeof($array) > 0) {
if ($someCondition) {
$entry = array_pop($array);
}
}
You often have no choice but to calculate it every iteration.