0

I have created two classes:

class TestClass
{
    public $id;
    public $name;
    public $time;
}

class TestClassCtor
{
    public $id;
    public $name;
    public $time;

    public function __construct()
    {
    }
}

Now I run a simple code:

$tt = microtime(true);
$data = array();
for ($i = 0; $i < 10000; $i++)
{
    $t = new TestClass();
    $t->id = rand();
    $t->name = rand();
    $t->time = rand();

    $data[] = $t;
}
echo microtime(true) - $tt;
echo "\n";    

$tt = microtime(true);
$data1 = array();
for ($i = 0; $i < 10000; $i++)
{
    $t = new TestClassCtor();
    $t->id = rand();
    $t->name = rand();
    $t->time = rand();

    $data1[] = $t;
}
echo microtime(true) - $tt;

Now, the second code with TestClassCtor is around 30% slower. Why? (tested with PHP 5.6 and 7.1).

Edit:

The similar difference can be spotted with (in this case, I can understand it - passing arguments to method may be slower).

class TestClassCtorFill
{
    public $id;
    public $name;
    public $time;

    public function __construct($id, $name, $time)
    {
        $this->id = $id;
        $this->name = $name;
        $this->time = $time;
    }
}

In this case, I can create class in one line as

for ($i = 0; $i < 10000; $i++)
{
    $data1[] =  new TestClassCtorFill(rand(), rand(), rand());
}

Yes, this is safer, because user must set all three parameters and he wont forget to set something.

However, when I use this inside my internal framework class, I can omit the ctor entirely and set members directly as with TestClass to save some time. For a few instances, this wont be a much of a difference. But if I create tousands of them, it could be.

Edit 2

I know about cost of a function call. However, constructor is called upon new, so if I write or not one, some constructor should be called. If there is no constructor provided by user a default one is caled. Memory for object must be allocated either way.

Martin Perry
  • 9,232
  • 8
  • 46
  • 114
  • I run it on sandbox - 0.0028159618377686 vs 0.0028159618377686 – splash58 Jan 27 '19 at 08:38
  • Each time you create a class with a constructor, there is an extra call (to the constructor) for each instance which is an overhead. BUT does it matter? If a constructor is the logical place to put code in, then it should be used. – Nigel Ren Jan 27 '19 at 08:39
  • Did not expect that... Just for the record, PHP 7.1 can repro. 25% diffrence – Koen Hollander Jan 27 '19 at 08:39
  • @NigelRen See my edit – Martin Perry Jan 27 '19 at 08:47
  • Having properties as `public` and setting them from your code like your `TestClass` is doing is very dangerous. This means that any coder can set them to anything they want, have a look at encapsulation to see why you would protect the way you implement your class. – Nigel Ren Jan 27 '19 at 08:51
  • @NigelRen this is basically a "struct", used instead of associative array. Its easier to manipulate with. – Martin Perry Jan 27 '19 at 08:53
  • 2
    Possible duplicate of [Why are PHP function calls \*so\* expensive?](https://stackoverflow.com/questions/3691625/why-are-php-function-calls-so-expensive) – yivi Jan 27 '19 at 10:36
  • @yivi Even if there is no constructor provided, some default constructor should be called and allocate memory, set default variable value etc. Only think that I can think of is, that this default ctor is optimized in native code and a part of PHP interpreter, so written in C/C++. – Martin Perry Jan 27 '19 at 11:01
  • If there is no constructor defined, not "default" constructor is called. Allocating memory is not the constructor job. The default properties values is set at compile time, so again, not the constructor's job. The question is an exact duplicate of that one: what you are discovering is that there is an overhead to calling functions/methods. – yivi Jan 27 '19 at 11:11
  • In 7.3.0 Win64 I get basically random figures every time I run the code and some times `TestClassCtor` is *faster*. PHP is being heavily optimised on each release and Rasmus Lerdorf explained in some conference that recent versions can even skip entirely blocks of code that do not do any actual work—perhaps an empty constructor qualifies as such. – Álvaro González Jan 27 '19 at 13:50
  • Wow, That's interesting. – Jovylle May 20 '21 at 10:49

0 Answers0