Tom's Tom's - 7 months ago 36
PHP Question

Strange use of class's variable (micro optimization ?)

I'm fairly new in PHP, and I encounter what I see as a strange use of class variable (I use PHP 5.6 and I think to use 7.0, if that help).

Class Foo {

private $bar = 'some string not returned nor modified and used in one place';

public function Test($foobar)
{
if ($foobar === $this->bar) {
// Some code
} else {
// Some code
}
}
}


When I see above code, I asked my co-worker why $bar is declared as a class variable, and why not declare $bar only in method 'Test'.
He answered by explaining me that declaring $bar in Test would result on a performance loss since each time method 'Test' will be call, it will result in re-create memory space for $bar variable.

I'm little puzzled, is this true ? I understand the logic : if you declare your variable as a class variable, memory will be "allocated" once and not at each call, but I'm surprised that there is no automatic optimization to do this behind the curtain by php.

Is this an old optimization ? It's a good thing to declare as much as possible variable as class variable ?

Sorry for such a question, but I searched a little and I found nothing (mostly because I don't know which keyword I must type to get information on this particular subject).

Answer Source

Here is a quick and dirty benchmark I have done with PHP 7.0 on my computer. I created three classes:

class Foo
{
    private $bar = 'some string not returned nor modified and used in one place';
    public function test($foobar)
    {
        if ($foobar === $this->bar) {}
    }
}

class Bar
{
    public function test($foobar)
    {
        $bar =  'some string not returned nor modified and used in one place';
        if ($foobar === $bar) {}
    }
}

class Baz
{
    public function test($foobar)
    {
        if ($foobar === 'some string not returned nor modified and used in one place') {}
    }
}

Then run something like:

$a = microtime(true);
for ($i=0; $i<10000000; $i++) {
    (new Foo)->test('pop');
}
echo microtime(true) - $a . "\n";

I runned it on each classes 10 times, and what I got is Bar and Baz seems to be faster every time.

So it's the exact opposite as what your coworker said.

Here is a sample result:

1.3472490310669 # foo
1.1803860664368 # bar
1.0683979988098 # baz

That said, two words:

  • My benchmark is dirty and does not prove anything.
  • I usually don't care about this kind of optimization (but I think you are already aware of micro-optimization debate)