| Date: | Fri, 11 Apr 2008 10:09:52 -0500 |
| Reply-To: | "data _null_," <datanull@GMAIL.COM> |
| Sender: | "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU> |
| From: | "data _null_," <datanull@GMAIL.COM> |
| Subject: | Re: Macro design / efficiency issues |
|
| In-Reply-To: | <OF2C1D1CBB.9CD9183A-ON85257428.004A7663-85257428.004EA247@freddiemac.com> |
| Content-Type: | text/plain; charset=ISO-8859-1 |
I will take the position that NO macro code is needed and that all of
this can be done with data steps and/or procs. Based on my
observation it looks like you are converting some character strings to
numbers for a list of variables and that each variable has an
associated format. I used an informat in the example because it is a
more direct. If you would like to provide a bit more information I
think you can find a nice none macro solution.
proc format;
invalue abseqD(upcase just) 'A'=1 'B'=2;
invalue adjsz2D(upcase just) 'C'=3 'D'=4;
invalue dratioD(upcase just) 'E'=5 'F'=6;
invalue mc044eD(upcase just) 'G'=7 'H'=8;
run;
data work.test;
array _y[*] abseq adjsz2 dratio mc044e;
informat abseq abseqD. adjsz2 adjsz2D. dratio dratioD. mc044e mc044eD.;
input _y[*];
cards;
a c e g
b d f H
;;;;
run;
proc print;
run;
On Fri, Apr 11, 2008 at 9:18 AM, Rushi Patel <rushi_patel@freddiemac.com> wrote:
> Hello SAS-L,
>
> We have coded two macros using different designs (refered in this email as
> design 1 and design 2) that get us what we want. Design 1 runs about 6
> times faster than design 2. Out of curiousity, I am trying to understand
> why this happens and would appreciate any insights from the group on this.
>
> Objective of the macro is to dynamically generate the statements similar
> to what are listed below, based on a list of variables provided to the
> macro.
>
> ABSEQPNT = INPUT(PUT(ABSEQ,ABSEQD.),8.);
> ADJSZ2PNT = INPUT(PUT(ADJSZ2,ADJSZ2D.),8.);
> DRATIOPNT = INPUT(PUT(DRATIO,DRATIOD.),8.);
> MC044EPNT = INPUT(PUT(MC044E,MC044ED.),8.);
> .....
> ......
> .....
>
> The points generated above - ABSEQPNT, ADJSZ2PNT, DRATIOPNT, MC044EPNT etc
> - are added up to get a score.
>
> Design 1 -
>
> I have coded a macro %XXXN(VAR=&VARNDFT) that generates the above
> statements based on what we have in the macro variable "VARNDFT".
>
> %MACRO XXXN ( VAR = ) ;
> %GLOBAL DEFN ;
> %LOCAL I STEP CODE ;
> %LET CODE = ;
> %LET DEFN = ;
> %LET I = 1 ;
> %LET STEP = %SCAN(&VAR,&I) ;
> %DO %WHILE (%LENGTH(&STEP) > 0 ) ;
>
> %LET CODE = &CODE &STEP.PNT %STR(=)
> INPUT(PUT(&STEP,&STEP.D.),8.)%STR(;);
> %LET DEFN = &DEFN &STEP.PNT ;
>
> %LET I = %EVAL(&I + 1 ) ;
> %LET STEP = %SCAN(&VAR,&I) ;
>
> %END ;
>
> &CODE
>
> %MEND XXXN ;
>
> The macro variable "CODE" stores the actual code - ABSEQPNT =
> INPUT(PUT(ABSEQ,ABSEQD.),8.) ; ..and when executed, will dump all this
> code in the data step within which its called.
> The macro variable "DEFN" stores a string - ABSEQPNT ADJSZ2PNT ...... -
> that is used outside the macro in the SUM function to sum up all the
> points and get a score.
>
> Design 2 -
>
> The other design that another programmer came up with includes the
> following macro. This macro is called within a data step and it also
> generates the statements outlined in the objectives (see above) within the
> datastep.
>
> Macro variable CNTNDFT stores the "number of variables" for which the code
> is to be generated.
> Macro variable VARPNDFT stores the ABSEQPNT etc variables list, which is
> created outside of the macro.
> Macro variable VARNDFT stores the list of variables ABSEQ etc for which
> the ABSEQPNT variables are defined.
>
> %MACRO SCRCARDS;
>
> %DO I=1 %TO &CNTCDFT;
>
> %SCAN(&VARNPDFT,&I) =
> INPUT(PUTN(%SCAN(&VARNDFT,&I),
> PUT("%SCAN(&VARNDFT,&I)",%STR($)NFMTD.)),8.);
> %END;
>
> ( The difference between Design 1 and design 2 is the layers of input and
> put statements used in this step. Here there is an addition layer of input
> / put functions used compared to design 1. This will increase the
> processing time a little, for each observation. But is a 6 fold increase
> justified simply by this difference?
> )
>
> DEFSCR = SUM(OF %DO I=1 %TO &CNTCDFT;
> %SCAN(&VARCPDFT,&I)
> %END;
> ,
> OF %DO I=1 %TO &CNTNDFT;
> %SCAN(&VARNPDFT,&I)
> %END;
> );
>
> %MEND SCRCARDS ;
>
> Design 1 is significantly (about 6 times less CPU time for the data step -
> on about 500,000 obs - in which these macros as called) faster. SAS on MVS
> TSO platform used.
>
> My apologizes for a lengthy email and not providing any test data.
>
> Thanks in advance.
>
> Rushi
>
|