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
Related
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
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 was reading sourses of OpenCart and phpBB engines and noticed that there are lot of strings (sometimes full screen listings) with repeated code, which differs only in one parameter. Such as:
$this->data['button_cart'] = $this->language->get('button_cart');
$this->data['button_wishlist'] = $this->language->get('button_wishlist');
$this->data['button_compare'] = $this->language->get('button_compare');
$this->data['button_continue'] = $this->language->get('button_continue');
I am thinking about using function for generating code using paterns, and then eval() it.
Some such function:
function CodeGenerator($patern, $placements_arr){
$echo_str = '';
foreach($placements_arr as $placement){
$echo_str .= str_replace('=PATERN=', $placement, $patern);
}
if(substr($echo_str, -1)!==';'){
$echo_str .= ';'; # for correct eval() working
}
return $echo_str;
}
And then for large repeated blocks of code with same patern:
$patern = "$this->data['=PATERN='] = $this->language->get('=PATERN=');";
$placements_arr = array('button_cart', 'button_wishlist', 'button_compare', 'button_continue');
$echo_str = CodeGenerator($patern, $placements_arr);
eval($echo_str);
I want to understand PRO and CONTRA of such design, because I am thinking about using such design in my future development.
The only problem I see here now - a bit more slow execution. Any others?
Well for the block of code you have shown you could rewrite it like this
$params = array('button_cart', 'button_wishlist', 'button_compare', 'button_continue');
foreach($params as $param)
$this->data[$param] = $this->language->get($param);
You are writing out the parameters anyways, so I cannot see one benefit to your code over something like what I have shown above. Plus this is only 3 lines of code vs 11 of yours, and mine is instantly readable
in 99.9% of the code you write, you can write it without eval. There are some corner cases where eval makes sense, but in my 5 years of coding php so far I have used it maybe one or 2 times, and if I went back to the code I could probably rewrite it so It didn't.
If I had to maintain a project with code that you wrote, I would be tearing my hair out. Just look at what OpenCart wrote, and look at what you wrote. Which one is easier to understand? I actually have to look at your code a few times to understand what it is doing, I can skim over the OpenCart code and instantly understand what is happening.
Maintainability - if that's a word - might be a small concern. I would despise such a construct because it seems unnecessarily complex. I have inherited many - a - poorly designed php sites working as a web developer and in just about zero cases can I recall it being considered a nuisance to have to spool through a list of var assignments like above. However, I would become infuriated by having to deal with weird lazy functions that attempt to escape the banalities of repetitive typing.
In the end you're talking about fractions of a second for processing so that's hardly an argument for doing something like this. And if the microseconds are a concern, use a caching mechanism to write to flat text and wipe out all redundant processing all together.
Hey, my 2 cents. If it's your project and you don't expect anyone else to maintain it then knock yourself out.
edit: wrong assumptions were made by my un-perfect self when I posted this question and I feel this question might be misleading.
The efficiency problem actually turned out to be unrelated to push_array.
The comments were helpful in helping me to understand that:
1)this should not take so long, and
2) diagnosing efficiency problems with microtime() is a good practice.
end edit
I am creating ~1400 objects in a test scenario. I think ~1400 will be within a magnitude of typical use.
public $t = Array();
...
for(...){
code...
for(...){
array_push($this->t, new T($i, $str)); //<--this line slows program.
count++;
}
code...
}
Unfortunately the script is taking about 90 seconds to run. If I comment out the one line of code with array_push, the script runs in about 1/6 the time, about 15 seconds.
The inner loop count varies, but averages about 3 to 15 cycles with one new object for each cycle.
Questions:
I am not an expert in PHP. I would like to know:
1) if it would help (and if so, how) to allocate memory space beforehand.
2) if there are any efficiency steps I should be taking that would help the script run faster or a data structure that would be more efficient then an array of objects. The newly created objects currently have two attributes, an integer and a string representing a single word (roughly averaging ~10 characters).
edit:
This is the constructor:
class T{
public $line;
public $text;
function __construct($ln, $txt){
$this->line = $ln;
$this->text = $txt;
}
}
The runtime depends on few different factors :
The server your using to run the script
Code efficiency of course - here's a great article about writing efficient php code
Of course there are more factors , but from previous exprience it shouldn't take that long , but still , the information I've got about the objects you're creating is not broad enough so I could detect where the problem is.
By the way, using PHP Accelerators such as APC or xcache might improve your code runtime.
What is the benefit of using multiple steps to test variables:
$VarLength = strlen($message);
if ($VarLength > 10)
echo "Over Ten";
...versus just pushing the whole process into one if statement:
if ( strlen($message) > 10 )
echo "Over Ten";
I'm wondering if the benefits go beyond code style, and the ability to re-use the results of the (in the example above) strlen result.
Your question is not really possible to answer technically, so this is more a comment than an answer.
Benefits beyond code-style and re-use of the result is when you change the code.
You might want to replace the strlen() function with some other function but you don't want to edit the line with the if clause while you do so. E.g. to prevent errors or side-effects. That could be a benefit, however it depends on code-style somehow. So as you exclude coding style from your question, it makes it hard to answer as that domain touches a lot how you can/should/would/want/must write code.
If the result of a function will be used multiple times, it should be cached in a variable so as to obviate the need to waste resources to re-calculate its result.
If the function result won't be re-used, it can simply be a matter of code readability to clearly delineate what's happening by storing the function return value in a variable before using it in an if condition.
Also, in terms of readability, you should always use curly braces even when not mandated by PHP syntax rules as #AlexHowansky mentions.
Most of it is in the code style. In terms of rapidity of the results, it doesn't change much. If you are using $varLenght more then once, then you are saving the call to the function to obtain the length. But even that, the time difference is extremely minimal (I would even like to say unnoticable).
But: When developping any applications, you have to keep in mind that you might not be the only one making changes to it down the road, or you might not be as fresh and up to date with the exact program you are writing. Therefore, the cleaner the code, the easier it is in terms of maintenance, and THAT'S where you save a lot of time down the road.
Best Practice dictates that functions be called minimally. In your case the practice doesn't violate the rule, but it is not uncommon to find code like:
if ( strlen($message) > 100 )
echo "Over Ten";
else if ( strlen($message) > 20 )
echo "Over Ten";
else if ( strlen($message) > 10 )
echo "Over Ten";
...
A common prevention is to always assign function results to a variable for consistency.
I wouldn't say there is any benefit apart from the re-use case you've already mentioned. Your latter case is more readable, probably faster, and probably less memory-intensive. I would however strongly recommend always using braces, even when your conditional is only one line:
if (condition) {
statement;
}