PHP behavior under the hood - php

I was just wondering how PHP works under the hood in this certain scenario. Let's say I have these two pieces of code:
function foo() {
return 2 * 2;
}
// First.
if (foo()) {
bar(foo());
}
// Second.
if (($ref = foo())) {
bar($ref);
}
Now the questions:
In the first case, does PHP make some sort of temporary variable inside the if clause? If so, isn't the second piece of code always better approach?
Does the second case take more memory? If answer to the first question is yes to the first question, then not?

The two codes are not equivalent, because the first one calls foo() twice (if it returns a truthy value). If it has side effects, such as printing something, they will be done twice. Or if it's dependent on something that can change (e.g. the contents of a file or database), the two calls may return different values. In your example where it just multiplies two numbers, this doesn't happen, but it still means it has to do an extra multiplication, which is unnecessary.
The answer to your questions is:
Yes, it needs to hold the returned value in a temporary memory location so it can test whether it's true or not.
Yes, it uses a little more memory. In the first version, the temporary memory can be reclaimed as soon as the if test is completed. In the second version, it will not be reclaimed until the variable $foo is reassigned or goes out of scope.

In the first case, you are calling a function twice, so, if the function is time consuming, it is inefficient. The second case is indeed better since you are saving the result of foo().
In both cases, PHP needs to allocate memory depending on what data foo() generates. That memory will be freed by the garbage collector later on. In terms of memory both cases are pretty much equivalent. Maybe the memory will be released earlier, maybe not, but most likely you won't encounter a case where it matters.

PHP can't make any temporary variable because it can't be sure that foo()'s returning value will always be the same. microtime(), rand() will return different values for each call, for example.
In the second example, it takes indeed more memory, since PHP needs to create and keep the value in memory.
Here is how to test it :
<?php
function foo() {
return true;
}
function bar($bool) {
echo memory_get_usage();
}
if (1) {
// 253632 bytes on my machine
if (foo()) {
bar(foo());
}
} else {
// 253720 bytes on my machine
if (($ref = foo())) {
bar($ref);
}
}

Related

What code cost more at performance level

Every body knows that today technology is low cost and many of us don't really care about it. So, take a look to this codes:
Approach #1
$Obj = new Obj();
if (!empty($val1)) {
$Obj->setVal1($val1);
}
if (!empty($val2)) {
$Obj->setVal2($val2);
}
if (!empty($val3)) {
$Obj->setVal3($val3);
}
if (!empty($valN)) {
$Obj->setValN($valN);
}
Approach #2
if (!empty($var1) && !empty($var2) && !empty($var3) && !empty($varN)) {
$Obj = new Obj();
if (!empty($val1)) {
$Obj->setVal1($val1);
}
if (!empty($val2)) {
$Obj->setVal2($val2);
}
if (!empty($val3)) {
$Obj->setVal3($val3);
}
if (!empty($valN)) {
$Obj->setValN($valN);
}
}
In the first example we're creating and object and leave around if none of the values exists, in the second one we are checking first if the values exists and aren't empty and then create the object and set the values. From your perspective which one would be the best solution in performance levels? Which one would you write on your codes?
Note: N is not infinite
Usually it's not operations like empty() or isset() that wastes time. Instead higher memory usage and memory leakage tends to lead to more GC operations, new() performs initialization that takes time, I/O operations causes delay, and that is where you should do your improvement.
It can be very very complex if you want to discuss the time usage in detail: during compilation, runtime, whether the code will run at all etc.
that is depend on what you want,
the first code will set value if it's not empty even tho' another value might be empty,
but the second code would check all of the value first, so if one of the value is empty, it will never create the Obj.
that is a clear choice,
if you think all value is important and necessary, then go with the second code, if it's fine to leave another value empty and want to update any value that is not empty there's no point on using the second code

Is it efficient to return an array in php?

I'm fairly new to PHP; most of my programming experience so far has been in C++. So, naturally, I get concerned about efficiency. In C++ you never ever ever return an object or an array at the end of a function, but if you need the data, you just return a pointer.
So my question is: is it bad for efficiency to be using arrays as return values, or does PHP just use a pointer in the background and just not show me for convenience?
PHP returns a reference if it's optimal for the interpreter to do so. Normally parameters passed to functions are copied, though you pass a parameter by reference and therefore get a return value by reference like so:
function blah(&$foo) {
$foo = array();//or whatever
//note no return statement
}
//elsewhere
$x = "whatever";
blah($x);
//$x is now an array.
Because of &, $foo is treated as a reference, and so modifications to that variable are treated as modifications to the reference.
Or you can force the function to return a reference:
function &blah() {
//some stuff
return $foo;//goes back as a reference
}
This latter shouldn't, according to the docs, be done unless you have a non-optimization reason to do so.
That said, PHP isn't terribly efficient, and worrying about these things is generally premature - unless you're seeing an actual performance bottleneck in your code.

Coding Style: function calls inside statements

Ok, first of all, i suspect this is going to be closed.
Right, i have a question relating to using function calls inside statements as opposed to assigning to a variable first.
For example:
(code is in php, but question applies generally. Also, code is overly simplified)
if (myAmazingFunction() === true) {
// do something amazing
}
instead of
$amazingresult = myAmazingFuncton();
if ($amazingResult === true) {
// do something amazing
}
The question is:
Is there any performance, or other underlying pros or cons to each approach
Stylistically, is any of the approaches considered better than the other
In most languages, there will be no performance difference. In the first case, the compiler will allocate storage for the result of the function call before checking whether it is true. In the second case you're simply making this explicit.
If you are debugging, sometimes the second form is easier, as you can set a breakpoint on the second line and check the value returned by the function before the comparison is made - but then you see the result of the function by the path the executing code takes anyway in the example you've given. You can also re-use the value without rerunning the function, as Zac says in his comment.
Stylistically, this is going to be largely subjective. The only thing I'd say here is that if your variable name makes the purpose of the function output clear, then you might be adding something to the ability for others to understand your code easily.
#DavidM's answer is correct. However, I'd just like to add that stylistically, I think it depends on the name of the function and its context.
Example:
if ($food->tastesGood()) {
echo 'Mmmm!';
}
// vs.
$foodTastesGood = $food->tastesGood();
if ($foodTastesGood) {
echo 'Mmmm!';
}
In this case, it's very clear that the return value of the method tastesGood() is going to be a boolean from both the name of the method and its context. Using a temporary variable adds nothing to your code except making it redundant and less-readable at a glance. In addition, if the variable is not defined right before its used, then you have to go find the definition to understand the condition. In these cases, I would say use of a variable is worse.
Another example:
if ($dishes->wash() !== FALSE) {
echo 'Sparkly!';
}
// vs.
$dishesAreClean = $dishes->wash() !== FALSE;
if ($dishesAreClean) {
echo 'Sparkly!';
}
In this case, we can't really infer the return type of the wash() method from its name, and indeed, it would seem that it returns nothing on success and FALSE on errors. Checking if the dishes are clean then requires us to make sure that there were no errors, but the first case doesn't make for particularly readable or self-documenting code. The second case, however, adds very explicit information about what's going on by way of the temporary variable. In these cases, I would say use of a variable is better.
Is there any performance, or other underlying pros or cons to each approach
Performance-wise, assigning an extra variable that you will use only in your if condition will use extra memory, and one useless line of code. So it will use more memory. Will it be noticeable? Probably not.
Stylistically, is any of the approaches considered bad
Using the method in your if statement is perfectly valid, and I think it's a better approach, since you can read the code and see exactly what value is being tested in the if condition. No need to look for the variable and search where it was affected.

Is there a way to check if the function expects a return value when called

I want to write a condition where I want to know if my function needs a return value or it can be executed as a procedure. Basically it should look like:
foo($x) {
$x++;
echo $x;
if(is_return_needed()) {
return $x;
}
}
where is_return_needed() is the condition if a return value is needed.
And how it should work:
echo foo(50); // should print AND return 51
bar(foo(50)); // should print AND return 51 to bar() function
foo(50); // should only print the value, because the returned value will not be used
And please don't tell me there's no reason to do this. I know I can send an additional boolean argument to the function which will be the condition, but is there a better way to achieve this?
Returning an object (or a large string), PHP will not make a copy of that object/string. That means returning alone, will not slow down your application. I found an article that explains it pretty well.
If the function can avoid building this large object at all, it will become faster. If you change the result of the function outside, or change it just before returning, it will become slower (is has to do the copy then). Building a long string with always adding a small part is very expensive, because every time it has to allocate a new big block of memory.
That said, we would have to see your code, to understand the slowdown you described. Returning a result only sometimes, is a very bad advice, every developer using your code will have a hard time to understand this behaviour. Sooner or later your application will become unstable if you use this often. Actually i find it even dangerous to return mixed typed values, as PHP often does itself.

What does PHP assignment operator do?

I happens to read this http://code.google.com/speed/articles/optimizing-php.html
It claims that this code
$description = strip_tags($_POST['description']);
echo $description;
should be optimized as below
echo strip_tags($_POST['description']);
However, in my understanding, assignment operation in PHP is not necessarily create a copy in memory.
This only have one copy of "abc" in memory.
$a = $b = "abc";
It consumes more memory only when one variable is changed.
$a = $b = "abc";
$a = "xyz";
Is that correct?
should be optimized as below
It's only a good idea if you don't need to store it, thereby avoiding unnecessary memory consumption. However, if you need to output the same thing again later, it's better to store it in a variable to avoid a another function call.
Is that correct?
Yes. It's called copy-on-write.
In the first example, if the variable is only used once then there is not point of making a variable in the first place, just echo the statements result right away, there is no need for the variable.
In the second example, PHP has something called copy on write. That means that if you have two variables that point to the same thing, they are both just pointing at the same bit of memory. That is until one of the variables is written to, then a copy is made, and the change is made to that copy.
The author does have a point insofar as copying data into a variable will keep that data in memory until the variable is unset. If you do not need the data again later, it's indeed wasted memory.
Otherwise there's no difference at all in peak memory consumption between the two methods, so his reasoning ("copying") is wrong.

Categories