PEAR is discontinued

This is a static archive preserving historical releases and metadata. No new packages or updates will be published. For updates to existing packages, or to publish new packages, please use Composer and Packagist.

Home » Database » DB » Bug #4185

Performances increased

Details

Request #4185Performances increased
Submitted2005-04-20 09:33 UTC
Fromfabien dot thierry at vie-medieval dot com
StatusWont fix
PackageDB
PHP Version5.0.3
OSLinux
Roadmaps(Not assigned)

Comments

[2005-04-20 09:33 UTC] fabien dot thierry at vie-medieval dot com

Description:
------------
I have a script which took 40% of his time (1250ms) in two methods:
_convertNullArrayValuesToEmpty and _rtrimArrayValues (called by fetchInto)

These two methods are quite identical. So, I have added a new method in Common.php, to use only one 'foreach'.
So, I have updated the fetchInto method to use this new method.

Now, the fetchInto execution time in my script is: 850ms (32% of gain)...

I have tested this update only with 'mysql.php'...

:-)

Reproduce code:
---------------
/***********************************************
* In the end of fetchInto method
***********************************************/
if ($this->options['portability'] & DB_PORTABILITY_RTRIM && $this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY){
$this->_rtrim_and_convertNullArrayValuesToEmpty($arr);
} else {
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
/*
* Even though this DBMS already trims output, we do this because
* a field might have intentional whitespace at the end that
* gets removed by DB_PORTABILITY_RTRIM under another driver.
*/
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
}

/***********************************************
* The new method in Common.php
***********************************************/
/**
* Convert all null values in an array to empty strings and rtrim string values
*
* @param array $array the array to be de-nullified (passed by reference)
* @return void
* @access private
*/
function _rtrim_and_convertNullArrayValuesToEmpty(&$array)
{
foreach ($array as $key => $value) {
if (is_null($value)) {
$array[$key] = '';
}elseif (is_string($value)) {
$array[$key] = rtrim($value);
}
}
}

Expected result:
----------------
Gain of performances

Actual result:
--------------
32% of gain

[2005-04-20 09:52 UTC] smith at backendmedia dot com

Maybe we should explore using http://www.php.net/array_walk here. then we dont need to use a foreach at all.

[2005-04-20 11:53 UTC] fabien dot thierry at vie-medieval dot com

I have tested array_walk by modifying 'my' method _rtrim_and_convertNullArrayValuesToEmpty.

So, array_walk is slowest: 1050ms (with array_walk) vs 850ms (with foreach)

This the code I used:

function _rtrim_and_convertNullArrayValuesToEmpty(&$array)
{
array_walk($array, array($this, '_rtrim_and_convertNullValueToEmpty'));
}

function _rtrim_and_convertNullValueToEmpty(&$item, $key){
if (is_null($item))
$item = '';
elseif (is_string($item))
$item = rtrim($item);
}

:-)

[2005-04-20 12:01 UTC] smith at backendmedia dot com

Now this is unexpected. I know this is not what you are drving at, but how about when just using rtrim() as the call back versus the _rtrimArrayValues() method?

[2005-04-20 12:16 UTC] fabien dot thierry at vie-medieval dot com

With the original code using array_walk, it is still worse!

This is the code:

/**************************
in mysql.php - method fetchInto
**************************/
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
array_walk($arr, array($this, '_rtrim_Value'));
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
array_walk($arr, array($this, '_convertNullValueToEmpty'));
}

/**************************
in common.php
**************************/
function _rtrim_Value(&$item, $key){
if (is_string($item)) {
$item = rtrim($item);
}
}
function _convertNullValueToEmpty(&$item, $key){
if (is_null($item)) {
$item = '';
}
}

**********************************************************
Conclusion:
1060 ms for _rtrim_Value
690 ms for _convertNullValueToEmpty

array_walk seems to be VERY SLOW: for each element of the array, it calls a method...

:-)

[2005-04-20 12:20 UTC] smith at backendmedia dot com

Erm no .. what I meant is:

if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
array_walk($arr, array($this, 'rtrim'));
}

then again that probably chews up NULL's

oh well. hmm i really think there has to be a more elegant mechanism to handle this... passing an array stack of functions to apply probably also doesnt fix the performance. I will ponder this a bit.

[2005-04-20 12:32 UTC] fabien dot thierry at vie-medieval dot com

With the code:

***************************************
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
array_walk($arr, 'rtrim');
}

if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
***************************************

The execution time is 1050ms. It is better than the original code (1250ms), but worse than the previous patch (850ms)...

:-)

[2005-04-20 13:03 UTC] fabien dot thierry at vie-medieval dot com

Sorry!

You are right!

The best way is the last (with array_walk($arr, 'rtrim')) and without my patch!

In conclusion:

fetchInto execution time in one of my scripts:

1) With the original code: 1690ms
2) With my 'patch': 1250ms
3) With array_walk($arr, 'rtrim') (in replacement of 1 line in fetchInto method): 1050ms

Congratulation, Smith!

[2005-04-20 13:05 UTC] smith at backendmedia dot com

Please test what rtrim() does to NULL values. Its entirely possible that someone only has rtrim enabled and not convert NULL to empty.

[2005-04-20 13:44 UTC] fabien dot thierry at vie-medieval dot com

oups!

I have added a patch to count how many null values there is before and after the array_walk.

So, I have seen any null values!!!

:-((