Speeding Up SugarCRM Soap Requests

 
Originally posted March 18, 2008
Brian Dailey

Brian Dailey is a LAMP-stack developer with a wide range of experience in the development world. Get in touch!

For more articles on the development trade, see the Blog.

(This applies to SugarCRM 5.0.x.)

If you're making SOAP requests with SugarCRM you've probably noticed that large requests can often take a lot of time (pulling in, for example, 200 contacts can take up to a minute). I have spent some time identifying where the slowdowns are occurring and thought this might be useful for some poor other shmuck out there that's forced to use SugarCRM.


The easiest modification is pretty obvious. In include/nusoap/nusoap.php on Line 56 you can change the default globalDebugLevel to 0.

The debugging in nusoap is the #1 culprit for the slowdown. There are a lot of calls to nusoap_base::debug() and nusoap_base::appendDebug(). Commenting these out will speed things up considerably. of course, if you need them (you probably will eventually!), you'll probably want to make a backup copy so you can view debug output.


In soap/SugarHelperFunctions.php I replaced

strcmp($str, 'string') == 0
with
$str == 'string'
I ran some tests and the strcmp runs significantly slower. Here's the relevant change.

202c202
<                               if($type === 'date'){
---
>                               if(strcmp($type, 'date') == 0){
204c204                            
<                               }elseif(($type === 'enum' || $type === 'radioenum') && !empty($var['options'])){
---
>                               }elseif((strcmp($type, 'enum') == 0 || strcmp($type, 'radioenum') == 0) && !empty($var['options'])){

In the same file, there is a place where the SugarCRM folks are using sizeof inside a for loop. For loops execute conditions on each loop. Unless you're changing the size of the array inside the loop, there's no reason you can't run the conditional outside (prior) the loop.

343,356c343,351
<       // SPEED IMPROVEMENT - BDAILEY
<       $max = count($output_list);
<       if($module_name == 'Contacts'){
<               global $invalid_contact_fields;
<               if (is_array($invalid_contact_fields)) {
<                       $loop_contact_fields = True;
<               }
<       }  
<       for($sug = 0; $sug < $max ; $sug++) {
<               if ($loop_contact_fields) {
<                       foreach($invalid_contact_fields as $name=>$val){
<                               unset($output_list[$sug]['field_list'][$name]);
<                               unset($output_list[$sug]['name_value_list'][$name]);
<
---
>       for($sug = 0; $sug < sizeof($output_list) ; $sug++){
>               if($module_name == 'Contacts'){
>                       global $invalid_contact_fields;
>                       if(is_array($invalid_contact_fields)){
>                               foreach($invalid_contact_fields as $name=>$val){
>                                       unset($output_list[$sug]['field_list'][$name]);
>                                       unset($output_list[$sug]['name_value_list'][$name]);
>  
>                               }

Last, you can comment out the debug functions in data/SugarBean.php. Comment out Lines 3177, 3232, 3275. Again, make a backup of this file in case you need to debug something later.

After you've put in these changes, you should notice a significant speed improvement when retrieving lots of records. It still isn't going to be lightning fast (nusoaps encoding algorithms are just too slow and would have to be entirely rewritten for further improvements... of course, now PHP5 has a built-in SoapClient which should be used).