Re: Introducing "Array Of" RFC

From: Date: Thu, 16 Jan 2014 10:49:17 +0000
Subject: Re: Introducing "Array Of" RFC
References: 1 2 3 4 5 6 7 8 9 10 11 12 13  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
Le 16/01/2014 11:01, [email protected] a écrit :
+ 1 for the RFC But if i'm not completely wrong, there is performance decrease instead of increase in your tests? https://gist.github.com/krakjoe/8444591 [joe@fiji php-src]$ sapi/cli/php isTest.php 10000 objects: 10000
arrayof:        0.00645113
instanceof:     0.00560713
I gave the RFC a few more thoughts and came to the conclusion that it does not fit to PHP (due to the performance penalties involved). The performance penalty is the same as if you were type-checking yourself. And on the gist linked, we can see that the results vary a lot (not enough iterations probably), it's easy to take only the worst one. Here, I'll take the one where the numbers are inversed to "prove" my point: [joe@fiji php-src]$ sapi/cli/php isTest.php 1000 objects: 1000
arrayof:        0.00080991
instanceof:     0.00086308
The syntax merely hide an ugly design. If you would write the same in normal PHP then probably everyone would agree that it is bad design.
How is type checking a bad design? Between: function (array $foos) {
    foreach ($foos as $foo) {
        if (! $foo instanceof Foo) {
            throw new InvalidArgumentException("...");
        }
        $foo->bar();
    }
} and: function (array $foos) {
    foreach ($foos as $foo) {
        $foo->bar(); // BOOM, fatal error if not correct object given
    }
} which one is worse? It's the same problem than this: function ($foo) {
    $foo->bar(); // fatal error if not correct object given
} and this: function (Foo $foo) {
    $foo->bar();
}
Following an example (doesn't really make sense but outlines the bad design) function foo(Foo[] $foos){
    if(count($foos) > 0){
       $a = array_pop($foos);
       //do something
      foo($foos);
    }
} Is equivalent to function foo(array $arr){
    foreach($arr as $v){
       if(!($v instanceof Foo)){
          //trigger_error
       }
    }
    if(count($foos) > 0){
       $a = array_pop($foos);
       //do something
      foo($foos);
    }
} The check adds runtime complexity to the function for each call which is obviously not necessary (once would be good enough). And I doubt that users would actually make sure that the check is only performed once and even if you would argue that one should write it as follows: function bar(Foo[] $foos){
    foo($foos);
} function foo(array $foos){
    if(count($foos) > 0){
       $a = array_pop($foos);
       //do something
      foo($foos);
    }
} Then it is still bad design compared to a collection which actually does the check during the addition of elements. Although, I like the effort to make PHP somewhat more type safe I am -1 for this RFC, the implementation respectively. If we want typed arrays then the array needs to carry the type to be efficient.
Matthieu

Thread (46 messages)

« previous php.internals (#71175) next »