Why is the script slow…


For a project I am working on migrating UNIX applications to Linux. Most of the scripting work supposed to be done in India, and that is where the issues came in. First you have a developer who knows how to work with M$ Technet and never worked with PERL before (at least 80% of the scripts is written in PERL).

First of all I introduced the user Net::LDAP within PERL, because they first did a ldapsearch, put the output into a ASCII file... and with a PERL script they structured the data... and loaded it into a Oracle database... so that was the first improvement.

Next there were several issues, like not good reading or understanding LDAP/PERL at all...

But at a certain moment, they start complaining about the fact that one of the scripts was slow... on the old system the script had a run time of 4 hours... and now it is up to 28 hours(!!!) :-( So they requested me to investigate this.

First I found a 'main' kornshell script doing the next thing:


for VAR in a b d e f g i j k m n o p q r s t u v w x y z
do
   for NAME in "'" a b c d e f g h i j k l m n o p q r s t u v w x y z
   do
     ldap_script.pl $NAME $VAR
   done
done


The content of the ldap_script.pl was something like:


#!/usr/bin/perl
use Net::LDAP;
$ldap = Net::LDAP->new($LDAP_SERVER);
$ldap->bind($LDAP_DN, password=>$LDAP_PASSWD) or die "Cannot connect";
$LDAP_FILTER="(&(sn=$ARGV[0]*)(OfficeName=$ARGV[1]*))";
$mesg = $ldap->search(base=>$LDAP_BASE,
                      filter=>$LDAP_FILTER,
                     ) or die "Cannot connect";
push(@ENTRIES,$mesg->entries);
$ldap->unbind;


I thought that this costs a lot... loading PERL script, connecting to server, binding to it... et cetera... :-( And this was done in the original script > 2000 times :-|

So... I removed the loop out of the mainscript... and implemented it into the PERL-script, like this:


#!/usr/bin/perl

use Net::LDAP;

$ldap = Net::LDAP->new($LDAP_SERVER);
@LOOP=("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o",
       "p","q","r","s","t","u","v","w","x","y","z", "'");


$ldap->bind($LDAP_DN, password=>$LDAP_PASSWD) or die "Cannot connect";

foreach $LOOP1 (@LOOP)
{
  foreach $LOOP2 (@LOOP)
  {
    
$LDAP_FILTER="(&(sn=$LOOP1*)(OfficeName=$LOOP2*))";
     $mesg = $ldap->search(base=>$LDAP_BASE,
                           filter=>$LDAP_FILTER,
                          ) or die "Cannot connect";
     push(@ENTRIES,$mesg->entries);
  }
}

$ldap->unbind;

And this runs within 3 hours!!! And it is flying! :-D

There can be done more performance tuning... but that will be another project!