プログラムの処理時間を計測したい - SAS
SASプログラムの処理時間は、1つのdataステップやプロシージャ単位でログに表示されるのだけど、複数ステップの合計処理時間を取得したい、プログラム全体の処理時間を知りたいとかあるかと思います。処理時間を計測するためには、現在の日時を取得する datetime関数を用いることで計測することができます。
処理時間を計測するテストコード
/* 処理時間を計測したい処理直前の日時をマクロ変数 START_TIME に格納 */
data _null_ ;
call symputx('START_TIME', datetime()) ;
run ;
/* 処理を計測したいサンプルコード */
data TEST1 ;
do I=1 to 10000000 ;
R = ranuni(1) ;
output ;
end ;
run ;
/* 処理直後の日時 - 処理直前の日時 = 処理時間 */
data _null_ ;
PROCESS_TIME = datetime() - &START_TIME. ;
putlog PROCESS_TIME= ;
run ;
処理時間を計測した実行ログ
59 data _null_ ;
60 call symputx('START_TIME', datetime()) ;
61 run ;
NOTE: DATAステートメント処理(合計処理時間):
処理時間 0.00 秒
CPU時間 0.01 秒
62
63 data TEST1 ;
64 do I=1 to 10000000 ;
65 R = ranuni(1) ;
66 output ;
67 end ;
68 run ;
NOTE: データセットWORK.TEST1は10,000,000オブザベーション、2変数です。
NOTE: DATAステートメント処理(合計処理時間):
処理時間 1.76 秒
CPU時間 0.84 秒
69
70 data _null_ ;
71 PROCESS_TIME = datetime() - &START_TIME. ;
72 putlog PROCESS_TIME= ;
73 run ;
PROCESS_TIME=1.8770267963
NOTE: DATAステートメント処理(合計処理時間):
処理時間 0.12 秒
CPU時間 0.01 秒
PROCESS_TIME=1.8770267963 という感じでログに処理時間が出力されています。単位は、秒です。
プログラム内で、何度も処理時間を計測したい場合は、上記のコードを何度も書くのは面倒なので、マクロ化してみましょう。処理時間をログに表示させるマクロは、他の方がやられているようなので(本記事下部の参考サイト参照)、実行日時をデータセットに格納して、最後に処理時間をリスト出力するマクロを作ってみます。
処理時間をリスト出力するマクロ
%macro CHECK_PROCESS_TIME(NAME) ;
/* 現在の実行日時を格納 */
data PROCESS_TIME_TMP ;
length NAME $256. ;
DT = datetime() ;
NAME = "&NAME." ;
run ;
/* データセット PROCESS_TIME_SUM がある場合、実行日時を追加 */
%if %sysfunc(exist(PROCESS_TIME_SUM)) %then %do ;
proc append base=PROCESS_TIME_SUM data=PROCESS_TIME_TMP ;
run ;
proc delete data=PROCESS_TIME_TMP ;
run ;
%end ;
/* データセット PROCESS_TIME_SUM がない場合、データセット名を変更 */
%else %do ;
proc datasets lib=WORK nolist ;
change PROCESS_TIME_TMP = PROCESS_TIME_SUM ;
quit ;
%end ;
%mend CHECK_PROCESS_TIME ;
%macro PRINT_PROCESS_TIME() ;
data PROCESS_TIME_TMP ;
set PROCESS_TIME_SUM ;
rename DT = DT_AFTER ;
run ;
/* 処理時間を計測する */
data PROCESS_TIME_PRINT ;
label NAME = "処理名"
PROCESS_TIME = "処理時間"
DT = "開始日時"
DT_AFTER = "終了日時"
;
format PROCESS_TIME comma10.2
DT nldatm30.
DT_AFTER nldatm30.
;
set PROCESS_TIME_SUM ;
set PROCESS_TIME_TMP(firstobs=2) ;
PROCESS_TIME = DT_AFTER - DT ;
run ;
proc print data=PROCESS_TIME_PRINT label ;
run ;
%mend PRINT_PROCESS_TIME ;
/* 以下、サンプルコード --------------------------------------- */
%CHECK_PROCESS_TIME(INIT) ;
data TEST1 ;
do I=1 to 10000000 ;
R = ranuni(1) ;
output ;
end ;
run ;
%CHECK_PROCESS_TIME(FIRST) ;
data TEST1 ;
do I=1 to 10000000 ;
R = ranuni(1) ;
output ;
end ;
run ;
%CHECK_PROCESS_TIME(SECOND) ;
/* 処理時間をリスト出力 */
%PRINT_PROCESS_TIME ;
ログに表示させるものだと、処理時間の出力結果が散らばってしまいますが、リスト出力するとぱっと見で処理時間を比較できるのが、メリットかと思います。
コメント
コメントを投稿