Hi,

I played with a patched version of compare_function with this optimization
in it. Other then for strings it didn't seem to make much of a difference. A
quick test showed that in an average php application only about 0.15% of
calls to compare_function actually have the same op1 and op2. Considering it
doesn't make much of a difference for anything except string comparison (and
maybe arrays?) it probably isnt worth putting it in compare_function. This
certinally is not a common case and would only serve to add an extra
needless comparison and branch to the other 99% of calls to
compare_function. Also, it seems as if in most cases this type of behavior
could be detected and handled appropriatly at compile time by a good
optimizer.

However, while the common compare_function call probably wouldent gain
anything from this, maybe it could be put in the TYPE_PAIR(IS_STRING,
IS_STRING) case or put into zendi_smart_strcmp (which only seems to ever be
called by the TYPE_PAIR(IS_STRING, IS_STRING) case of compare_function).

I havent played with the patched version of zend_hash_compare to see if it
might provide any real world savings. Though it appears as if that function
might see a significant improvement for these cases.

~ Graham Kelly

On Tue, Nov 4, 2008 at 4:53 PM, Lukas Kahwe Smith <[EMAIL PROTECTED]>wrote:

> Hello again,
>
> once again top posting this this is fairly old ..
> however for something that is sounding so promising I am wondering why this
> hasnt been picked up ..
>
> regards,
> Lukas
>
>
> On 20.10.2008, at 22:09, shire wrote:
>
>
>> On Oct 19, 2008, at 12:11 PM, Karoly Negyesi wrote:
>>
>>  Hi,
>>>
>>> I think zend_hash_compare could get a healthy speed boost in some
>>> cases if first it would check whether the two variables passed to it
>>> are actually the same (because of "reference counting"). Sorry, my C
>>> skills are way too rusty to write the patch which is likely to be just
>>> a few lines long.
>>>
>>>
>>
>> A quick patch/test seems to agree with you, I'd be interested to know if
>> you/others  are able to apply this patch and see any real-world savings with
>> your web application.  The following was done with a debug build of PHP so
>> results are likely exaggerated.  I'm also using non-recursive array with 256
>> byte strings below, results with numeric values are less significant of
>> course (approx a 25% gain)...
>>
>> I'll also look into applying this to some other functions like
>> compare_function where it's likely to yield a larger savings in a general
>> application.
>>
>>
>> patch against php-5.2 CVS head
>> --------------------------
>> iff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
>> index a1d7071..d11785f 100644
>> --- a/Zend/zend_hash.c
>> +++ b/Zend/zend_hash.c
>> @@ -1327,16 +1327,14 @@ ZEND_API int zend_hash_compare(HashTable *ht1,
>> HashTable *ht2, compare_func_t co
>>       IS_CONSISTENT(ht1);
>>       IS_CONSISTENT(ht2);
>>
>> -       HASH_PROTECT_RECURSION(ht1);
>> -       HASH_PROTECT_RECURSION(ht2);
>> -
>>       result = ht1->nNumOfElements - ht2->nNumOfElements;
>> -       if (result!=0) {
>> -               HASH_UNPROTECT_RECURSION(ht1);
>> -               HASH_UNPROTECT_RECURSION(ht2);
>> +       if (ht1 == ht2 || result!=0) {
>>               return result;
>>       }
>>
>> +       HASH_PROTECT_RECURSION(ht1);
>> +       HASH_PROTECT_RECURSION(ht2);
>> +
>>       p1 = ht1->pListHead;
>>       if (ordered) {
>>               p2 = ht2->pListHead;
>>
>>
>>
>> simple test script
>> -------------------------------
>> <?php
>>
>> $arr1 = array();
>> for ($i=0; $i < 10000; $i++) {
>>  $arr1[$i] = str_repeat('x', 256);
>> }
>> $arr2 = array();
>> for ($i=0; $i < 10000; $i++) {
>>  $arr2[$i] = str_repeat('x', 256);
>> }
>> $arr3 = $arr1;
>>
>> $count = 0;
>> $start = microtime(true);
>> for ($i = 0; $i < 1000; $i++) {
>>  if ($arr1 == $arr2) {
>>   $count++;
>>  }
>> }
>> $stop = microtime(true);
>> echo "different array time: ".($stop-$start)."\n";
>> echo "count: $count \n";
>>
>> $count = 0;
>> $start = microtime(true);
>> for ($i = 0; $i < 1000; $i++) {
>>  if ($arr1 == $arr3) {
>>   $count++;
>>  }
>> }
>> $stop = microtime(true);
>> echo "identical array time: ".($stop-$start)."\n";
>> echo "count: $count \n";
>> -------------------------------
>>
>> (un-patched php build)
>> [EMAIL PROTECTED]:~/data/php/git/php$ ./sapi/cli/php.vanilla test.php
>> different array time: 4.2019698619843
>> count: 1000
>> identical array time: 2.4957029819489
>> count: 1000
>>
>> (patched build)
>> [EMAIL PROTECTED]:~/data/php/git/php$ ./sapi/cli/php test.php
>> different array time: 4.059928894043
>> count: 1000
>> identical array time: 0.00043511390686035
>> count: 1000
>>
>>
>> -shire
>>
>> --
>> PHP Internals - PHP Runtime Development Mailing List
>> To unsubscribe, visit: http://www.php.net/unsub.php
>>
>>
> Lukas Kahwe Smith
> [EMAIL PROTECTED]
>
>
>
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

Reply via email to