Welcome! Log In Create A New Profile

Advanced

[PHP-DEV] Small question about performance

Posted by Klaus Silveira 
Klaus Silveira
[PHP-DEV] Small question about performance
March 15, 2012 03:30PM
Hello internals,

I've been involved in a discussion at the PHP Standards Group and we
recently had the following statement:

*Say you had a loop, and inside that loop you wanted to modify a param
> **update the key:**
> **foreach($a as $key => $val) {
> ** $a[$key] = someLong(functionCalls(hereThat($spanOver85Chars)));
> **}**
> **If this exceeded the line width, you would have to split things like
> **this over a few lines, storing the val temporarily in a zval's until
> **you reached your end computation. Therefore allocating more memory
> **iteratively. *


I'm curious about this. Can anyone confirm it or a benchmark should be
made?
Richard Lynch
Re: [PHP-DEV] Small question about performance
March 15, 2012 03:50PM
On Thu, March 15, 2012 9:21 am, Klaus Silveira wrote:
> Hello internals,
>
> I've been involved in a discussion at the PHP Standards Group and we
> recently had the following statement:
>
> *Say you had a loop, and inside that loop you wanted to modify a param
>> **update the key:**
>> **foreach($a as $key => $val) {
>> ** $a[$key] = someLong(functionCalls(hereThat($spanOver85Chars)));
>> **}**
>> **If this exceeded the line width, you would have to split things
>> like
>> **this over a few lines, storing the val temporarily in a zval's
>> until
>> **you reached your end computation. Therefore allocating more memory
>> **iteratively. *
>
>
> I'm curious about this. Can anyone confirm it or a benchmark should be
> made?

I don't see why your standard can't allow for:
$a[$key] =
someLong(
functionCalls(
hereThat(
$spanOver85Chars
) ) );

Some folks insist that the closing parens be on separate lines.
They're isomorphic to me, so I just put them on one line.

So long as the count matches and they "line up" in reverse order,
indented properly, it's all good.

But then, I cut my teeth on Lisp, where a zillion parens to close off
almost anything is the norm. :-)

PS
If you want a benchmark for how much 3 or 4 temporary zvals takes,
knock yourself out.

Also consider trying this in a second benchmark:

//don't create / destroy zvals in the loop, hopefully
$someLong = '';
$functionCalls = '';
$hereThat = '';
foreach ($a as $key => $value){
...
}

PPS
I'm assuming $a is not within the Coding Standard :-)


--
brain cancer update:
http://richardlynch.blogspot.com/search/label/brain%20tumor
Donate:
https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FS9NLTNEEKWBE



--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Nikita Popov
Re: [PHP-DEV] Small question about performance
March 15, 2012 04:00PM
On Thu, Mar 15, 2012 at 3:21 PM, Klaus Silveira <[email protected]> wrote:
> Hello internals,
>
> I've been involved in a discussion at the PHP Standards Group and we
> recently had the following statement:
>
> *Say you had a loop, and inside that loop you wanted to modify a param
>> **update the key:**
>> **foreach($a as $key => $val) {
>> **   $a[$key] = someLong(functionCalls(hereThat($spanOver85Chars)));
>> **}**
>> **If this exceeded the line width, you would have to split things like
>> **this over a few lines, storing the val temporarily in a zval's until
>> **you reached your end computation. Therefore allocating more memory
>> **iteratively. *
If I am understanding the text correctly it is saying that
$f1 = f1();
$f2 = f2($f1);
$f3 = f3($f2);
is using more memory than
$f3 = f3(f2(f1()));

For me this doesn't make any sense. In the latter case PHP will also
create temporary variables to store the return values. There should be
no difference in memory consumption.

Nikita

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Patrick ALLAERT
Re: [PHP-DEV] Small question about performance
March 15, 2012 05:30PM
2012/3/15 Nikita Popov <[email protected]>:
> If I am understanding the text correctly it is saying that
>    $f1 = f1();
>    $f2 = f2($f1);
>    $f3 = f3($f2);
> is using more memory than
>    $f3 = f3(f2(f1()));
>
> For me this doesn't make any sense. In the latter case PHP will also
> create temporary variables to store the return values. There should be
> no difference in memory consumption.

It does make sense to me.

In the first case, when calling f3(), $f1 is still referenced.
In the second case, when calling f3(), the result of f2() is
referenced, but there is no more active reference to the result of
f1().

Regarding the original problem:
foreach($a as $key => $val) {
$a[$key] = someLong(functionCalls(hereThat($spanOver85Chars)));
}

Sounds easier to split over lines without temporary zvals:
foreach($a as $key => $val) {
$a[$key] = someLong(
functionCalls(
hereThat(
$spanOver85Chars
)
)
);
}

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Michael Stowe
Re: [PHP-DEV] Small question about performance
March 15, 2012 05:40PM
Just to elaborate on what Patrick said, in the first case the variables are
temporary, where in the second they persist even after you finish your
loop. So even after the foreach is finished, the $f1, $f2, and $f3
variables are still storing data- even though it is no longer needed.

In order to free up the memory allocated to these variables you'd have to
unset them after they're used in the loop, or after the loop has finished.

- Mike




On Thu, Mar 15, 2012 at 11:22 AM, Patrick ALLAERT <[email protected]>wrote:

> 2012/3/15 Nikita Popov <[email protected]>:
> > If I am understanding the text correctly it is saying that
> > $f1 = f1();
> > $f2 = f2($f1);
> > $f3 = f3($f2);
> > is using more memory than
> > $f3 = f3(f2(f1()));
> >
> > For me this doesn't make any sense. In the latter case PHP will also
> > create temporary variables to store the return values. There should be
> > no difference in memory consumption.
>
> It does make sense to me.
>
> In the first case, when calling f3(), $f1 is still referenced.
> In the second case, when calling f3(), the result of f2() is
> referenced, but there is no more active reference to the result of
> f1().
>
> Regarding the original problem:
> foreach($a as $key => $val) {
> $a[$key] = someLong(functionCalls(hereThat($spanOver85Chars)));
> }
>
> Sounds easier to split over lines without temporary zvals:
> foreach($a as $key => $val) {
> $a[$key] = someLong(
> functionCalls(
> hereThat(
> $spanOver85Chars
> )
> )
> );
> }
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


--
-----------------------

"My command is this: Love each other as I
have loved you." John 15:12

-----------------------
Stas Malyshev
Re: [PHP-DEV] Small question about performance
March 15, 2012 06:00PM
Hi!

> If I am understanding the text correctly it is saying that
> $f1 = f1();
> $f2 = f2($f1);
> $f3 = f3($f2);
> is using more memory than
> $f3 = f3(f2(f1()));

Short answer: it doesn't matter, use either as you wish.

Long answer: Technically, the former also uses hash buckets to bind
values to the symbol table, so it can use more memory (and if it so
happens that using these variables makes symbol table go over hashtable
threshold, hashtable internal storage size will be increased), so it
will consume marginally more memory. But the difference is completely
negligible.

--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Nikita Popov
Re: [PHP-DEV] Small question about performance
March 15, 2012 06:00PM
On Thu, Mar 15, 2012 at 5:22 PM, Patrick ALLAERT <[email protected]> wrote:
> 2012/3/15 Nikita Popov <[email protected]>:
>> If I am understanding the text correctly it is saying that
>>    $f1 = f1();
>>    $f2 = f2($f1);
>>    $f3 = f3($f2);
>> is using more memory than
>>    $f3 = f3(f2(f1()));
>>
>> For me this doesn't make any sense. In the latter case PHP will also
>> create temporary variables to store the return values. There should be
>> no difference in memory consumption.
>
> It does make sense to me.
>
> In the first case, when calling f3(), $f1 is still referenced.
> In the second case, when calling f3(), the result of f2() is
> referenced, but there is no more active reference to the result of
> f1().
I don't really know when PHP frees temporary variables, but my guess
was that they are freed when the scope is left.

If that is not true, then forget whatever I said.

But if it is true, then there is no inherent difference between the
two version. The only difference is that explicit $variables would
need an entry in the active symbol table, which is pretty much
negligible.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Paul Dragoonis
Re: [PHP-DEV] Small question about performance
March 15, 2012 06:50PM
On Thu, Mar 15, 2012 at 4:54 PM, Nikita Popov <[email protected]> wrote:
> On Thu, Mar 15, 2012 at 5:22 PM, Patrick ALLAERT <[email protected]> wrote:
>> 2012/3/15 Nikita Popov <[email protected]>:
>>> If I am understanding the text correctly it is saying that
>>>    $f1 = f1();
>>>    $f2 = f2($f1);
>>>    $f3 = f3($f2);
>>> is using more memory than
>>>    $f3 = f3(f2(f1()));
>>>
>>> For me this doesn't make any sense. In the latter case PHP will also
>>> create temporary variables to store the return values. There should be
>>> no difference in memory consumption.
>>
>> It does make sense to me.
>>
>> In the first case, when calling f3(), $f1 is still referenced.
>> In the second case, when calling f3(), the result of f2() is
>> referenced, but there is no more active reference to the result of
>> f1().
> I don't really know when PHP frees temporary variables, but my guess
> was that they are freed when the scope is left.

Each variable has a refcount, then that hits 0 it can be freed up.

>
> If that is not true, then forget whatever I said.
>
> But if it is true, then there is no inherent difference between the
> two version. The only difference is that explicit $variables would
> need an entry in the active symbol table, which is pretty much
> negligible.
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Paul Dragoonis
Re: [PHP-DEV] Small question about performance
March 15, 2012 06:50PM
On Thu, Mar 15, 2012 at 5:39 PM, Paul Dragoonis <[email protected]> wrote:
> On Thu, Mar 15, 2012 at 4:54 PM, Nikita Popov <[email protected]> wrote:
>> On Thu, Mar 15, 2012 at 5:22 PM, Patrick ALLAERT <[email protected]> wrote:
>>> 2012/3/15 Nikita Popov <[email protected]>:
>>>> If I am understanding the text correctly it is saying that
>>>>    $f1 = f1();
>>>>    $f2 = f2($f1);
>>>>    $f3 = f3($f2);
>>>> is using more memory than
>>>>    $f3 = f3(f2(f1()));
>>>>
>>>> For me this doesn't make any sense. In the latter case PHP will also
>>>> create temporary variables to store the return values. There should be
>>>> no difference in memory consumption.
>>>
>>> It does make sense to me.
>>>
>>> In the first case, when calling f3(), $f1 is still referenced.
>>> In the second case, when calling f3(), the result of f2() is
>>> referenced, but there is no more active reference to the result of
>>> f1().
>> I don't really know when PHP frees temporary variables, but my guess
>> was that they are freed when the scope is left.
>
> Each variable has a refcount, then that hits 0 it can be freed up.

To add to that. A zval will have a refcount, so if you do $a =
someFunc(); then $a will have a refcount.

If you do something like $a = someFunc(anotherFunc(moreFunc())), the
return values of anotherFunc() and moreFunc() will be temp stored, but
they will _not_ have a refcount because they never got assigned into a
zval like $a.

Hope that made sense.

>
>>
>> If that is not true, then forget whatever I said.
>>
>> But if it is true, then there is no inherent difference between the
>> two version. The only difference is that explicit $variables would
>> need an entry in the active symbol table, which is pretty much
>> negligible.
>>
>> --
>> PHP Internals - PHP Runtime Development Mailing List
>> To unsubscribe, visit: http://www.php.net/unsub.php
>>

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Reindl Harald
Re: [PHP-DEV] Small question about performance
March 15, 2012 08:10PM
Am 15.03.2012 18:41, schrieb Paul Dragoonis:
>>> I don't really know when PHP frees temporary variables, but my guess
>>> was that they are freed when the scope is left.
>>
>> Each variable has a refcount, then that hits 0 it can be freed up.
>
> To add to that. A zval will have a refcount, so if you do $a =
> someFunc(); then $a will have a refcount.
>
> If you do something like $a = someFunc(anotherFunc(moreFunc())), the
> return values of anotherFunc() and moreFunc() will be temp stored, but
> they will _not_ have a refcount because they never got assigned into a
> zval like $a.

to make sure i understand this really

function myfunc()
{
$b = internal_function_with_hughe_return_value();
return false;
}

$b is freed after the function has finished
if not i should write a lot of unset() what
is not possible if you have return $b
Michael Stowe
Re: [PHP-DEV] Small question about performance
March 15, 2012 08:20PM
The $b on this example would be freed as it is in the function's scope, and
not the global scope. The exception to this would be a static variable
within a function, which would persist for future use within the function.

Class properties on the other hand will persist until the object is
destructed, or until they are unset.

So for your example,
function test() {
$b = 'apple';
return $b;
}

You would not need to unset $b as it resides temporarily within the
function, and does not persist outside of the function.

- Mike




On Thu, Mar 15, 2012 at 1:58 PM, Reindl Harald <[email protected]>wrote:

>
>
> Am 15.03.2012 18:41, schrieb Paul Dragoonis:
> >>> I don't really know when PHP frees temporary variables, but my guess
> >>> was that they are freed when the scope is left.
> >>
> >> Each variable has a refcount, then that hits 0 it can be freed up.
> >
> > To add to that. A zval will have a refcount, so if you do $a =
> > someFunc(); then $a will have a refcount.
> >
> > If you do something like $a = someFunc(anotherFunc(moreFunc())), the
> > return values of anotherFunc() and moreFunc() will be temp stored, but
> > they will _not_ have a refcount because they never got assigned into a
> > zval like $a.
>
> to make sure i understand this really
>
> function myfunc()
> {
> $b = internal_function_with_hughe_return_value();
> return false;
> }
>
> $b is freed after the function has finished
> if not i should write a lot of unset() what
> is not possible if you have return $b
>
>
>
>
>


--
-----------------------

"My command is this: Love each other as I
have loved you." John 15:12

-----------------------
Reindl Harald
Re: [PHP-DEV] Small question about performance
March 15, 2012 08:20PM
thanks

exactly what i assumed, but better to be sure instead
wasting somewhere ressources without need :-)

Am 15.03.2012 20:10, schrieb Michael Stowe:
> The $b on this example would be freed as it is in the function's scope, and
> not the global scope. The exception to this would be a static variable
> within a function, which would persist for future use within the function.
>
> Class properties on the other hand will persist until the object is
> destructed, or until they are unset.
>
> So for your example,
> function test() {
> $b = 'apple';
> return $b;
> }
>
> You would not need to unset $b as it resides temporarily within the
> function, and does not persist outside of the function.
Sorry, only registered users may post in this forum.

Click here to login