覆盖现有的SAS数据集需要更多时间吗?

NEO*_*men 8 sas

我得到一个简短的问题 - 如果我们正在创建一个SAS数据集说 - 已经存在的Sample.sas7bdat,代码将花费更多时间来执行(因为这里代码必须覆盖现有数据集),而不是此数据集不是已经在那了?

data sample;
.....
.....
run;
Run Code Online (Sandbox Code Playgroud)

我在互联网上做了一些研究,但找不到满意的答案.对我来说,似乎代码应该花费一些额外的时间,但不确定它会对10GB的数据集产生多大的影响.

Joe*_*Joe 5

你可以很容易地自己测试一下.一些警告:

  • 确保您拥有足够大的数据集,以便您不会错过简单随机cpu活动的差异.100 + MB通常是一个很好的目标.
  • 确保多次执行测试 - 越多越好,如果可能的话,两者之间没有时间.一个测试总是不够充分,并且总是倾向于将第一个数据集显示得更快,因为它受益于写入缓存(基本上操作系统表示它已完成写入而不是,但只是将写入排队在内存中).

这是我的测试的一个例子.这是一个1亿行数据集,有两个8字节的数字,所以1.6 GB.

一,结果.我看到了几点差异.为什么?更换数据集时,SAS会执行一些操作:

Write dataset to temporary file
Delete the old dataset
Rename temporary dataset to new dataset
Run Code Online (Sandbox Code Playgroud)

在某些操作系统上,这似乎比其他操作系统更快; 我发现Windows桌面相对于unix甚至Windows Server操作系统而言相当慢.我猜测Windows更简单地删除而不是简单地更改文件系统指针,但我真的不知道.它肯定不是从实用程序目录复制整个文件(它还没有足够的时间).我还怀疑写缓存仍然会给新数据集带来一些推动,特别是随着我写的所有数据集的时间越来越长.差异可能只有大约一秒左右 - _REP迭代2和_NEW迭代3之间的差异对我来说似乎是最合理的.

Iteration 1 _NEW=7.26999998099927 _REP=12.9079999922978
Iteration 2 _NEW=10.0119998454974 _REP=11.0789999961998
Iteration 3 _NEW=10.1360001564025 _REP=15.3819999695042
Iteration 4 _NEW=14.7720000743938 _REP=17.4649999142056
Iteration 5 _NEW=16.2560000418961 _REP=19.2009999752044
Run Code Online (Sandbox Code Playgroud)

请注意,第一次迭代new比其他迭代快得多,并且总体时间随着时间的推移而增加(因为写入缓存越来越不能跟上).我怀疑如果你允许它继续(或者使用更大的文件,我现在没有时间),你可能会看到更加一致的时间.当删除写缓存的文件时,我也不确定写缓存会发生什么.在执行删除操作或类似操作之前,它可能必须等待写入缓存写入磁盘.您可以执行测试,在_NEW和_REP之间等待30秒以验证.

代码:

%macro test_me(iter=1);
%do _i=1 %to &iter.;
%let start = %sysfunc(time());
data test&_i.;
  do x = 1 to 1e8;
    y=x**2;
    output;
  end;
run;
%let mid=%sysfunc(time());
data test&_i.;
  do x = 1 to 1e8;
    y=x**2;
    output;
  end;
run;
%let end=%sysfunc(time());
%let _new = %sysevalf(&mid.-&start.);
%let _rep = %sysevalf(&end.-&mid.);

%put Iteration &_i. &=_new. &=_rep.;
%end;

proc datasets nolist kill;
quit;
%mend test_me;

options nosource nonotes nomprint nosymbolgen;

%test_me(iter=5);
Run Code Online (Sandbox Code Playgroud)