Is PHP Magic faster than just setting a class attribute?

Well, not really, but here is an example. Can someone explain the difference between B and C? How can I use a magic function to set a value dynamically instead of just setting a value in an attribute definition?

Here is the code:

[root@vm-202-167-238-17 ~]# cat test.php; for d in A B C; do echo "------"; ./test.php $d; done;
#!/usr/bin/php
<?php

$className = $argv[1];

class A
{
    public function __get($a)
    {
        return 5;
    }
}

class B
{
    public $a = 5;
}

class C
{
    public function __get($a)
    {
        $this->a = 5;

        return 5;
    }
}

$a = new $className;

$start = microtime(true);

for ($i=0; $i < 1000000; $i++)
    $b = $a->a;

$end = microtime(true);

echo (($end - $start) * 1000) ." msec\n";

------
598.90794754028 msec
------
205.48391342163 msec
------
189.7759437561 msec
+3
source share
2 answers

The magic functions are certainly slower than anything else in PHP and should be used carefully. In fact, it will be a good blog subject (automatic creation of attributes using magic functions to speed up work ... anyway). As El Yobo stated , I modified your PHP script so that the tests are more accurate:

<?php

class A {
    public function __get($a) {
        return 5;
    }
}

class B {
    public $a = 5;
}

class C {
    private $a = 5;
    public function __get($a) {
        return $this->a;
    }
}

$classes = array('A','B','C');

header('Content-type: text/plain; charset=utf-8');
foreach ($classes as $className) {
   $a = new $className;

   $start = microtime(true);

   for ($i=0; $i < 1000000; $i++) {
      $b = $a->a;
   }

   $end = microtime(true);

   echo 'Class ' . get_class($a) . ' = ' . (($end - $start) * 1000) ." msec\n";
}

Result

Class A = 378.85212898254 msec
Class B = 109.26413536072 msec
Class C = 423.51794242859 msec

, . , , , 4 , .

** EDIT **

, , , ( ). C :

class C {
    public function __get($a) {
        $this->a = 5;
        return 5;
    }
}

Class A = 392.09413528442 msec
Class B = 110.16988754272 msec
Class C = 96.771955490112 msec

, : ", !" , 1000000 10 ():

Class A = 0.033140182495117 msec
Class B = 0.0078678131103516 msec
Class C = 0.01215934753418 msec

C , B, . , PHP , . , , , , PHP .. , , , , .

** 2 **

D, :

class D {
   public function __construct() {
      $this->a = 5;
   }
}

1000 :

Class A = 1.3999938964844 msec
Class B = 0.42200088500977 msec
Class C = 0.3960132598877 msec
Class D = 0.37002563476562 msec       <-- faster

1 000 000:

Class A = 380.80310821533 msec
Class B = 109.7559928894 msec
Class C = 91.224908828735 msec        <-- faster ???
Class D = 96.340894699097 msec

, : ,

public function __get($a) {
   $this->a = 5;
   return 5;
}

,

public function __construct() {
   $this->a = 5;
}

?

+4

( C) "a" ; , ; , , .

: B , C. , ; , C B A, A B C, C , B, , PHP; , , , C, , B ( , ). , ( ) A , B 5.2.10 5.3.3.

, ; ( , ) __get. , __get. ; , (, public $a) .

$className = $argv[1];

class A
{
    public function __construct() {
        $this->a = 5;
    }
}

class B extends A
{
    public $a;
}

$a = new $className;

$start = microtime(true);

for ($i=0; $i < 1000000; $i++)
    $b = $a->a;

$end = microtime(true);

echo (($end - $start) * 1000) ." msec\n";
+2

Source: https://habr.com/ru/post/1781378/


All Articles