Re: [PECL-DEV] Re: shared memory extention

[email protected] (Geoffrey McRae) Fri, 16 Apr 2010 10:43:51 +1000
Newsgroups php.pecl.dev
Message-ID <1271378631.4170.16.camel@geoff>
Ok, I now understand whats going on with the zvals and I have figured
out how to setup the array references properly.

I have chosen to go with the PHP licence, so I just need to add the
required files, comments etc, and clean up the code as per PHP
standards.

Anyway, here is a simple benchmark to test the performance of my
unserialize code vs unserialize

<?PHP
        $b = '123';
        $array = array(
                'ref1' => &$b,
                'ref2' => &$b,
                'norm' => $b
        );
        $array['self'] = &$array;
        unset($b);

        $a = serialize(&$array);
        sm_set('test', &$array);

        $time = microtime(true);
        for($i = 0; $i < 100000; ++$i)
                unserialize($a);
        echo "unserialize: " . (microtime(true) - $time) . "\n";

        $time = microtime(true);
        for($i = 0; $i < 100000; ++$i)
                sm_get('test');
        echo "sm_get     : " . (microtime(true) - $time) . "\n";
?>

Outputs:

unserialize: 0.18884897232056
sm_get     : 0.15477204322815

My unserialization code is much faster then unserialize, which I did not
expect.

They both provide identical output with debug_zval_dump

-Geoff


On Fri, 2010-04-16 at 09:56 +1000, Geoffrey McRae wrote:
> On Thu, 2010-04-15 at 14:29 -0700, Stanislav Malyshev wrote:
> > Hi!
> > 
> > > Or even better yet, is there a way to compare two zval's and see if they
> > > are pointing to the the same data?
> > 
> > Two different zvals shouldn't be pointing to the same data unless 
> > they're objects, in which case they'd have same handler table and object 
> > ID values.
> > 
> > You may want to look at serialization code in ext/standard/var.c for an 
> > example of how you deal with references when serializing.
> 
> Ok, I think I have actually found a bug in php itself, since the
> serialize function does not behave as expected...
> 
> If serialize is called by value, a new zval is provided and the
> serialize function cant detect first level references back to itself.
> See the sample code provided and its output.
> 
> <?PHP
>         $b = '123';
>         $array = array(
>                 'ref1' => &$b,
>                 'ref2' => &$b,
>                 'norm' => $b
>         );
>         $array['self'] = &$array;
> 
>         serialize(&$array) . "\n";
>         serialize($array) . "\n";
> ?>
> 
> Outputs:
> 
> a:4:{s:4:"ref1";s:3:"123";s:4:"ref2";R:2;s:4:"norm";s:3:"123";s:4:"self";R:1;}
> a:4:{s:4:"ref1";s:3:"123";s:4:"ref2";R:2;s:4:"norm";s:3:"123";s:4:"self";a:4:{s:4:"ref1";R:2;s:4:"ref2";R:2;s:4:"norm";s:3:"123";s:4:"self";R:4;}}
> 
> If this is not a bug, it should be documented on the serialize function
> at php.net to pass its value by ref, but it would make more sense to fix
> the function, someone has already noticed this issue here:
> http://www.php.net/manual/en/function.serialize.php#93313
> 
> I am plagued by the same problem in my serialization code, if I pass by
> ref things work fine.
> 
> -Geoff