MVSFORUMS.com Forum Index MVSFORUMS.com
A Community of and for MVS Professionals
 
 FAQFAQ   SearchSearch   Quick Manuals   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Performance issue with LMLIST/LMCOPY in REXX

 
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> TSO and ISPF
View previous topic :: View next topic  
Author Message
chandra
Beginner


Joined: 26 Sep 2003
Posts: 130
Topics: 36

PostPosted: Thu Aug 20, 2009 11:32 am    Post subject: Performance issue with LMLIST/LMCOPY in REXX Reply with quote

Hi All,

I have written a REXX program to copy the matching members into one PDS and non matching members into another PDS from my input PDS.

I am running this rexx job through JCL and it is taking more then 210 mins .

I have 13000 members in my input PDS. Can you please let me know how I can increase my job performance.

Code:
/* REXX */

/**********************************************************************
* Author : Chandra                                                    *
*                                                                     *
* Input  : In INDD, first row must be pds name in the following format*
*          DSN=PDS.NAME                                               *
*          Search string should be MEM=SRCHSTR*                       *
* Output : Job names that matches the MEM name                        *
**********************************************************************/

wmem = ' '

"ALLOC F(INDD) OLD REUSE"
"EXECIO * DISKR INDD (STEM inrec. FINIS"     /* read input jcl */


"ALLOC F(JCLLIST) DSORG(PS) SPACE(2,0) TRACKS", /* Output jobnames */
       "LRECL(80) RECFM(F,B) NEW"

Do i = 1 To inrec.0

  If Substr(inrec.i,1,3) = 'DSN' Then
      lib = Strip(Substr(inrec.i,5,44))
  Else
    Do
      wmem.i =Strip(Substr(inrec.i,5,10))
      wmem.i = Substr(wmem.i,1,Length(wmem.i)-1)
      lmem.i = Length(wmem.i)
      smem.i = wmem.i
    End
End

If lmem.3 < 0 Then lmem.3 = 5          /* if no string ass dft val */
If lmem.4 < 0 Then lmem.4 = 5          /* if no string ass dft val */
If lmem.5 < 0 Then lmem.5 = 5          /* if no string ass dft val */
If lmem.6 < 0 Then lmem.6 = 5          /* if no string ass dft val */

/* Read all job names from input dataset */

ADDRESS TSO "ALLOC F(MYPDS) DA('"lib"') SHR REU"
ADDRESS ISPEXEC "CONTROL ERRORS RETURN"
ADDRESS ISPEXEC "LMINIT DATAID(LISTM) DDNAME(MYPDS) ENQ(SHRW)"
ADDRESS ISPEXEC "LMOPEN DATAID("LISTM") OPTION(INPUT)"

/* To copy all the jobs that matches the input */

"ALLOC F(injobs) DSORG(PO) SPACE(400,40) DIR(2000)",
       "CYLINDERS LRECL(80) RECFM(F,B) NEW"
ADDRESS ISPEXEC "LMINIT DATAID(INMEM) DDNAME(INJOBS) ENQ(SHRW)"

/* To copy all the jobs that doesnot matches the input */
"ALLOC F(exjobs) DSORG(PO) SPACE(400,40) DIR(2000)",
       "CYLINDERS LRECL(80) RECFM(F,B) NEW"
ADDRESS ISPEXEC "LMINIT DATAID(EXMEM) DDNAME(EXJOBS) ENQ(SHRW)"

Do Until list_rc >= 8

  ADDRESS ISPEXEC "LMMLIST DATAID(&LISTM) OPTION(LIST) MEMBER(wmem)"
  list_rc = RC

  If (Substr(wmem,1,lmem.2) = smem.2) |,
     (Substr(wmem,1,lmem.3) = smem.3) |,
     (Substr(wmem,1,lmem.4) = smem.4) |,
     (Substr(wmem,1,lmem.4) = smem.5) |,
     (Substr(wmem,1,lmem.5) = smem.6) Then
    Do
      /* To write the job names in the dataset */
      Push wmem
      "Execio 1 diskw JCLLIST"
      /* To Copy the jobs that matches the input */
      ADDRESS ISPEXEC "LMCOPY FROMID(&LISTM)",
          " FROMMEM("WMEM") TODATAID(&INMEM)"

    End
  Else
    Do
      /* To Copy the jobs that doesnot  matches the input */
      ADDRESS ISPEXEC "LMCOPY FROMID(&LISTM)",
          " FROMMEM("WMEM") TODATAID(&EXMEM)"
    End
End


ADDRESS ISPEXEC "LMCLOSE DATAID(&LISTM)"
ADDRESS ISPEXEC "LMFREE  DATAID(&LISTM)"

ADDRESS ISPEXEC "LMCLOSE DATAID(&INMEM)"
ADDRESS ISPEXEC "LMFREE  DATAID(&INMEM)"

ADDRESS ISPEXEC "LMCLOSE DATAID(&EXMEM)"
ADDRESS ISPEXEC "LMFREE  DATAID(&EXMEM)"


"EXECIO 0 diskr JCLLIST (finis"
"EXECIO 0 diskr MYPDS   (finis"
"EXECIO 0 diskr INDD   (finis"
"EXECIO 0 diskr INMEM  (finis"
"EXECIO 0 diskr EXMEM  (finis"

"free f(JCLLIST)"
"free f(MYPDS)"
"free f(INDD)"
"free f(INMEM)"
"free f(EXMEM)"
EXIT

_________________
Regards,
Chandra
Back to top
View user's profile Send private message
semigeezer
Supermod


Joined: 03 Jan 2003
Posts: 1014
Topics: 13
Location: Atlantis

PostPosted: Thu Aug 20, 2009 4:59 pm    Post subject: Reply with quote

I don't know why it is taking so long, but this is probably is opening and closing the data set and updating the directory (slow!) with each LMCOPY. I would suggest one of 2 alternate strategies:

  1. Use the PATTERN() parameter of LMMLIST instead of your own parsing and then write SELECT M=(name) statements as input for IEBCOPY which you can then run either in your exec or as a batch job (hint.. alloc SYSUT1, SYSUT2, SYSPRINT DUMMY and SYSIN DUMMY, then SELECT PGM(IEBCOPY))
  2. Copy the entire dataset to the not found destination and then use LMMOVE with a pattern to move the found members to the found data set. If you can use IEBCOPY for the initial copy, all the better because IEBCOPY only writes the directory once (assuming this is a PDS and not a PDSE).

Either strategy should be faster than doing individual copies. The 1st strategy would be fastest.
_________________
New members are encouraged to read the How To Ask Questions The Smart Way FAQ at http://www.catb.org/~esr/faqs/smart-questions.html.
Back to top
View user's profile Send private message Visit poster's website
Dibakar
Advanced


Joined: 02 Dec 2002
Posts: 700
Topics: 63
Location: USA

PostPosted: Thu Aug 20, 2009 5:22 pm    Post subject: Reply with quote

I am assuming chandra doesn't have a pattern, then I would probably use IEBCOPY (in REXX or JCL) by creating below sysin before calling IEBCOPY

Code:

//COPYMEMS EXEC  PGM=IEBCOPY                       
//SYSUT1   DD  DSN=CHANDRA.FULL,DISP=SHR
//SYSUT2   DD  DSN=CHANDRA.MATCHING,DISP=SHR             
//SYSUT3   DD  DSN=CHANDRA.NOMATCH,DISP=SHR             
//SYSPRINT DD  SYSOUT=*                           
//SYSIN    DD  *                                   
  COPY OUTDD=SYSUT2,INDD=SYSUT1                   
    SELECT MEMBER=((MATCH1,,R))                   
    SELECT MEMBER=((MATCH2,,R))                   
    SELECT MEMBER=((MATCH3,,R))                   
    SELECT MEMBER=((MATCH4,,R))                   
  COPY OUTDD=SYSUT3,INDD=SYSUT1                   
    SELECT MEMBER=((NOMATCH1,,R))                 
    SELECT MEMBER=((NOMATCH2,,R))                 
    SELECT MEMBER=((NOMATCH3,,R))                 
    SELECT MEMBER=((NOMATCH4,,R))                 
Back to top
View user's profile Send private message Send e-mail
chandra
Beginner


Joined: 26 Sep 2003
Posts: 130
Topics: 36

PostPosted: Thu Aug 20, 2009 10:25 pm    Post subject: Reply with quote

Thank you very much Semigeezer and Dibakar.

I have changed my program to build the sysin parameter as shown by Diba and ran the IEBCOPY step through JCL and now it is running very fast now.

Thanks once again !!!

I have one more question, The program is running fine and I am getting the results but I am getting following messages in SYSPRINT. Can you let me know why I am getting these.
Code:


READY
 ISPSTART CMD(JOBLIST)
MISSING DATA SET NAME+
MISSING NAME OF DATA SET TO BE ALLOCATED
FILE JCLLIST NOT ALLOCATED, FILE IN USE
FILE INJOBS NOT ALLOCATED, FILE IN USE
FILE EXJOBS NOT ALLOCATED, FILE IN USE
FILE INMEM NOT FREED, IS NOT ALLOCATED
FILE EXMEM NOT FREED, IS NOT ALLOCATED
 $9KV.$9KVA.JOB15666.D0000107.? was preallocated (no free was done).
READY
END


The modified program is

Code:

/* REXX */

/**********************************************************************
* Author : Chandra Darur                                              *
*                                                                     *
* Input  : In INDD, first row must be pds name in the following format*
*          DSN=PDS.NAME                                               *
*          Search string should be MEM=SRCHSTR*                       *
* Output : Job names that matches the MEM name                        *
* "ALLOC FI(INDD) SHR REUSE"                                          *
* "ALLOC F(JCLLIST) DA('TS09347.CMD35.DATASETS') OLD REUSE"           *
**********************************************************************/

wmem = ' '

"ALLOC F(INDD) OLD REUSE"
"EXECIO * DISKR INDD (STEM inrec. FINIS"     /* read input jcl */

"ALLOC F(JCLLIST) DSORG(PS) SPACE(2,0) TRACKS", /* Output jobnames */
       "LRECL(80) RECFM(F,B) NEW"

Do i = 1 To inrec.0

  If Substr(inrec.i,1,3) = 'DSN' Then
      lib = Strip(Substr(inrec.i,5,44))
  Else
    Do
      wmem.i =Strip(Substr(inrec.i,5,10))
      wmem.i = Substr(wmem.i,1,Length(wmem.i)-1)
      lmem.i = Length(wmem.i)
      smem.i = wmem.i
    End
End

If lmem.3 < 0 Then lmem.3 = 5          /* if no string ass dft val */
If lmem.4 < 0 Then lmem.4 = 5          /* if no string ass dft val */
If lmem.5 < 0 Then lmem.5 = 5          /* if no string ass dft val */
If lmem.6 < 0 Then lmem.6 = 5          /* if no string ass dft val */

/* Read all job names from input dataset */

ADDRESS TSO "ALLOC F(MYPDS) DA('"lib"') SHR REU"
ADDRESS ISPEXEC "CONTROL ERRORS RETURN"
ADDRESS ISPEXEC "LMINIT DATAID(LISTM) DDNAME(MYPDS) ENQ(SHRW)"
ADDRESS ISPEXEC "LMOPEN DATAID("LISTM") OPTION(INPUT)"

/* To write the sysin cards for IEBCOPY for matching members */

"ALLOC F(injobs) DSORG(PS) SPACE(2,1)",
       "CYLINDERS LRECL(80) RECFM(F,B) NEW"

Push "  COPY OUTDD=SYSUT2,INDD=SYSUT1"
"Execio 1 diskw injobs"
/* To write the sysin cards for IEBCOPY for non matching members */

"ALLOC F(exjobs) DSORG(PS) SPACE(2,1)",
       "CYLINDERS LRECL(80) RECFM(F,B) NEW"

Push "  COPY OUTDD=SYSUT2,INDD=SYSUT1"
"Execio 1 diskw exjobs"

Do Until list_rc >= 8

  ADDRESS ISPEXEC "LMMLIST DATAID(&LISTM) OPTION(LIST) MEMBER(wmem)"
  list_rc = RC

  If (Substr(wmem,1,lmem.2) = smem.2) |,
     (Substr(wmem,1,lmem.3) = smem.3) |,
     (Substr(wmem,1,lmem.4) = smem.4) |,
     (Substr(wmem,1,lmem.4) = smem.5) |,
     (Substr(wmem,1,lmem.5) = smem.6) Then
    Do
      /* To write the job names in the dataset */
      Push wmem
      "Execio 1 diskw JCLLIST"

      /* To Copy the jobs that matches the input */
      imem = Strip(wmem)
      Push "    SELECT MEMBER=((" || imem || ",,R))"
      "Execio 1 diskw injobs"

    End
  Else
    Do
      /* To Copy the jobs that doesnot  matches the input */
      imem = Strip(wmem)
      Push "    SELECT MEMBER=((" || imem || ",,R))"
      "Execio 1 diskw exjobs"
    End
End


ADDRESS ISPEXEC "LMCLOSE DATAID(&LISTM)"
ADDRESS ISPEXEC "LMFREE  DATAID(&LISTM)"


"EXECIO 0 diskr JCLLIST (finis"
"EXECIO 0 diskr MYPDS   (finis"
"EXECIO 0 diskr INDD   (finis"
"EXECIO 0 diskr INMEM  (finis"
"EXECIO 0 diskr EXMEM  (finis"

"free f(JCLLIST)"
"free f(MYPDS)"
"free f(INDD)"
"free f(INMEM)"
"free f(EXMEM)"

EXIT

_________________
Regards,
Chandra
Back to top
View user's profile Send private message
semigeezer
Supermod


Joined: 03 Jan 2003
Posts: 1014
Topics: 13
Location: Atlantis

PostPosted: Fri Aug 21, 2009 11:49 am    Post subject: Reply with quote

The ddnames are already allocated, probably because of a previous error. Add the REUSE parameter on the ALLOC commands:

"ALLOC F(JCLLIST) DSORG(PS) SPACE(2,0) TRACKS", /* Output jobnames */
"LRECL(80) RECFM(F,B) NEW REUSE"
_________________
New members are encouraged to read the How To Ask Questions The Smart Way FAQ at http://www.catb.org/~esr/faqs/smart-questions.html.
Back to top
View user's profile Send private message Visit poster's website
Dibakar
Advanced


Joined: 02 Dec 2002
Posts: 700
Topics: 63
Location: USA

PostPosted: Thu Aug 27, 2009 6:53 pm    Post subject: Reply with quote

chandra, long it takes now compared to 210 mins earlier?
Back to top
View user's profile Send private message Send e-mail
chandra
Beginner


Joined: 26 Sep 2003
Posts: 130
Topics: 36

PostPosted: Fri Aug 28, 2009 10:01 am    Post subject: Reply with quote

Hi Diba,

Now my REXX program (Which builds the SYSIN cards for IEBCOPY) is taking 1.11 mins and IEBCOPY is taking 0.38 mins to copy all the members.

Thank you very much for your suggeston.

Semigeezer - When I use REUSE in the dataset defination it is not working
_________________
Regards,
Chandra
Back to top
View user's profile Send private message
Dibakar
Advanced


Joined: 02 Dec 2002
Posts: 700
Topics: 63
Location: USA

PostPosted: Fri Aug 28, 2009 2:28 pm    Post subject: Reply with quote

Chandra,

Reuse will not solve if you already have the error. Try logoff logon and submit again.

But you need to fix other errors before that, as semigeezer has already mentioned. Check -

Code:
"ALLOC F(INDD) OLD REUSE"


If you are specifying the dataset in JCL then you don't need alloc and free in REXX. Same is true about other datasets.

Diba
Back to top
View user's profile Send private message Send e-mail
chandra
Beginner


Joined: 26 Sep 2003
Posts: 130
Topics: 36

PostPosted: Fri Aug 28, 2009 3:28 pm    Post subject: Reply with quote

Hi Diba,

I removed the ALLOC and FREE statements from my REXX program and it is working fine. I didn't know that before.

Thank you very much.
_________________
Regards,
Chandra
Back to top
View user's profile Send private message
Dibakar
Advanced


Joined: 02 Dec 2002
Posts: 700
Topics: 63
Location: USA

PostPosted: Wed Sep 02, 2009 3:41 pm    Post subject: Reply with quote

you are welcome
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> TSO and ISPF All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


MVSFORUMS
Powered by phpBB © 2001, 2005 phpBB Group