SAS provides addrlong, peeklong functions and pokelong call routine to move/copy data from memory(in this case temporary arry) directly. The call sortn and mean function can be used as vectorized calculations. This makes the following cVaR caculation astounding fast.
Here is a link for more detailed information,
http://www2.sas.com/proceedings/sugi29/264-29.pdf
*****************************************************
719 %let nvar=50;
720
721 data simu;
722
723 array x(*) x1-x&nvar;
724
725 do i=1 to 1000000;
726 do j=1 to dim(x);
727 x(j)=rannor(-1);
728 end;
729 output;
730 end;
731
732 run;
NOTE: The data set WORK.SIMU has 1000000 observations and 52 variables.
NOTE: DATA statement used (Total process time):
real time 6.20 seconds
user cpu time 4.61 seconds
system cpu time 1.06 seconds
memory 422.90k
OS Memory 12772.00k
Timestamp 05/12/2014 07:49:22 PM
Step Count 26 Switch Count 0
733
734 data _null_;
735 set simu nobs=nobs;
736 call symputx('nobs', nobs);
737 stop;
738 run;
NOTE: There were 1 observations read from the data set WORK.SIMU.
NOTE: DATA statement used (Total process time):
real time 0.37 seconds
user cpu time 0.00 seconds
system cpu time 0.00 seconds
memory 381.09k
OS Memory 12772.00k
Timestamp 05/12/2014 07:49:22 PM
Step Count 27 Switch Count 0
739
740 %macro cVarL(n);
741
742
743 %do i=1 %to &n;
744 %let percentile=%sysevalf((5+(&i-1)*10)/100);
745 %let idx=%sysfunc(putn((5+(&i-1)*10),z2.));
746
747 ***calculate cVar****;
748
749 max_n=int((&nobs-ceil(&percentile*&nobs)+1)/4095);
750 mod_n=mod((&nobs-ceil(&percentile*&nobs)+1),4095);
751 start_point=ceil(&percentile*&nobs);
752
753 do i=1 to max_n;
754 call pokelong(peekclong (addrlong(_y(start_point+(i-1)*4095 )) , 4095*8) ,
755 addrlong(cVarL&idx.(1+(i-1)*4095)), 4095*8);
756 end;
757 if mod_n >0 then
758 call pokelong(peekclong (addrlong(_y(start_point+(i-1)*4095)) , mod_n*8) ,
759 addrlong(cVarL&idx.(1+(i-1)*4095)), mod_n*8);
760
761 cVar&idx.=mean(of cVarL&idx.(*));
762 %end;
763 %mend;
764
765 options nomprint fullstimer;
766
767 data cVar;
768
769 array _x(&nvar, &nobs) _temporary_ ;
770 array _y(&nobs) _temporary_;
771
772 array cVarL05(%sysfunc(ceil(&nobs-0.05*&nobs+1))) _temporary_;
773 array cVarL15(%sysfunc(ceil(&nobs-0.15*&nobs+1))) _temporary_;
774 array cVarL25(%sysfunc(ceil(&nobs-0.25*&nobs+1))) _temporary_;
775 array cVarL35(%sysfunc(ceil(&nobs-0.35*&nobs+1))) _temporary_;
776 array cVarL45(%sysfunc(ceil(&nobs-0.45*&nobs+1))) _temporary_;
777 array cVarL55(%sysfunc(ceil(&nobs-0.55*&nobs+1))) _temporary_;
778 array cVarL65(%sysfunc(ceil(&nobs-0.65*&nobs+1))) _temporary_;
779 array cVarL75(%sysfunc(ceil(&nobs-0.75*&nobs+1))) _temporary_;
780 array cVarL85(%sysfunc(ceil(&nobs-0.85*&nobs+1))) _temporary_;
781 array cVarL95(%sysfunc(ceil(&nobs-0.95*&nobs+1))) _temporary_;
782
783
784 array cVar(10) cVar05 cVar15 cVar25 cVar35 cVar45
785 cVar55 cVar65 cVar75 cVar85 cVar95
786 ;
787
788
789
790 do until(end);
791
792 set simu end=end;
793
794 array x(*) x1-x&nvar;
795
796 n+1;
797
798 do i=1 to &nvar;
799
800 _x(i,n)=x(i);
801
802 end;
803
804 end;
805
806
807
808 do k=1 to &nvar;
809
810 ***copy all _x values to _y;
811 modname=vname (x(k));
812
813 max_n=int(&nobs/4095);
814 mod_n=mod(&nobs,4095);
815 start_point=1;
816
817
818
819 do i=1 to max_n;
820 call pokelong(peekclong (addrlong(_x(k, start_point+(i-1)*4095 )) , 4095*8) ,
821 addrlong(_y(start_point+(i-1)*4095)), 4095*8);
822 end;
823 if mod_n >0 then
824 call pokelong(peekclong (addrlong(_x(k, start_point+(i-1)*4095)) , mod_n*8) ,
825 addrlong(_y(start_point+(i-1)*4095)), mod_n*8);
826 call sortn(of _y(*));
827
828 %cVarL(10);
829
830 output;
831
832 end;
833
834 keep modname cVar:;
835
836 run;
NOTE: There were 1000000 observations read from the data set WORK.SIMU.
NOTE: The data set WORK.CVAR has 50 observations and 11 variables.
NOTE: DATA statement used (Total process time):
real time 12.25 seconds
user cpu time 11.32 seconds
system cpu time 0.85 seconds
memory 1060309.21k
OS Memory 1132432.00k
Timestamp 05/12/2014 07:49:35 PM
Step Count 28 Switch Count 0
837
838 proc means data=cVar;
839 var cVar:;
840 run;
NOTE: There were 50 observations read from the data set WORK.CVAR.
NOTE: PROCEDURE MEANS used (Total process time):
real time 0.01 seconds
user cpu time 0.00 seconds
system cpu time 0.03 seconds
memory 6123.00k
OS Memory 17912.00k
Timestamp 05/12/2014 07:49:35 PM
Step Count 29 Switch Count 0