楼主: yzzhang
2952 18

[原创博文] 这样两种写法运行效率差别大吗? [推广有奖]

11
chenjung0825 发表于 2010-5-10 11:34:21
我觉得区别在IO操作数上。

12
zhentao 发表于 2010-5-10 11:41:06
yzzhang 发表于 2010-5-7 21:19
但是我按两种方法在eg上测试了下,两者的cpu时间几本上没有差别
测试的数据有几十字段,只处理一个字段,记录数在千万左右;
cpu时间分别是
a方法8:08.70
b方法8:02.76  
貌似后者还快点,两次都是后者稍快点,所以才产生疑问;

个人认为碰到run语句代码编译完毕,在读入时,sas会自动忽略不读在整个程序中没有出现的变量。
那是因为你试的数据集较小。反应时间基本都是0.如果你用一个大的数据集就可以看出两者之间的速度了。
但是现在pc机的速度也很快,也省不了多少时间。

13
crackman 发表于 2010-5-10 11:44:53
哥们你说的数据多少才叫不小啊呢?
亿级的哇?

14
zhentao 发表于 2010-5-10 12:14:54
13# crackman

我用的数据集最大的一个有1t。是关于股票的高频数据的。

15
nkwilling 发表于 2010-5-10 12:39:44
KEEP=选项放在括号里面比KEEP语句放在外面效率高,根源在于PDV.crackman的解释非常形象.如果你测不出时间差异,说明你用的数据太少,或者原来数据集的变量个数太少.

16
yatming 发表于 2010-5-10 22:38:32
15# nkwilling
我再来补充一下。
keep=放在括号里面并不一定比放在外面效率高,要分情况来看。
其实keep=的data set option也要分两种情况:
1.KEEP= on SET statement
2.KEEP= on DATA statement

data step的运行机制用the little sas book的经典的话就是line by line,所以KEEP= on DATA statement这个情况其实和keep statement(即keep放在外面)的效率是相似的,是对于在pdv中的每条observation都要做keep计算,和buffers无关。一般data step中的效率问题基本上都集中在一个方面,就是buffers到pdv这个阶段,如果数据在buffers中做完过滤,那么就不需要在pdv中迭代逐条来做重复的过滤动作浪费时间,而set statement的data set option中过滤一般都是直接对buffers进行过滤。所以其效率要更高一些,不过也要看情况(楼主就有个很好的例子,以下会说到),当然由于直接走的是buffers,CPU和IO的消耗也会大一些。

还有关于where statement,它有些特殊,和where= data set option一样,都是对buffers进行过滤。if statement就不用说了,其过滤动作在pdv中迭代进行。

所以楼主的1楼的贴子为何表b还稍显快的原因就在这:
data a(keep=x1);——虽然下面的set statement中已经有了对buffers的过滤,但是这里的keep无疑是对pdv的过滤,
                                  即使buffers加载给pdv的数据已经没有了变量x1,但这个keep造成的计算仍然在执行,因此这里这条语句会产生额外的计算
     set table(keep=x1 where=(x1>100));——where和keep都是对buffers的过滤。
run;

data b;
     set table;
     where x1>100;——where仍然是对buffers进行过滤
     keep x1;——keep则是对pdv进行过滤
run;

因此可以看到由于表a相比表b,都对pdv进行了keep过滤和对buffers进行了where过滤,但不同的是,表a还对buffers进行keep过滤,此计算量的增加造成了效率的损失。

继续解释9楼的结果:

22         
23         data a2;
24         set table(keep=x where=(x='0000497604'));
25         run;
NOTE: “DATA 语句”所用时间(总处理时间):
      实际时间         45.79 秒
      CPU 时间         4.09 秒
      
NOTE: 从数据集 WORK.TABLE 读取了 2 个观测。
      WHERE x='0000497604';
NOTE: 数据集 WORK.A2 有 2 个观测和 1 个变量。
26         data b2;
27         set table;
28         keep x;
29         where x='0000497604';
30         run;
NOTE: “DATA 语句”所用时间(总处理时间):
      实际时间         44.18 秒
      CPU 时间         3.95 秒

这里有点特殊,个人感觉这段代码由于结果只有2条observation,所以效率分析更加麻烦。以下仅供参考:前者对buffers的计算是where和keep,后者只是where,后者还对pdv进行了keep计算。在对计算量进行分析之前,基于40+s的运行时间,因此做这样一个保守假设,假设原数据有1W条observation,而前者和后者的where效率,没问题,一致的,那么效率的差异就体现在双方keep的计算量上,虽然前者的keep是对buffers进行过滤,但buffers只是一个缓冲且有定长,依赖于memory,所以它并不足以大到可以吃掉整个dataset,关于buffers大小,proc contents可以看到,所以buffers的load是分块的,其频数个人认为等于contents中的number of pages,因此前者keep的计算量应该是等同于buffers的load频数,而后者,keep是对pdv中observation进行计算,这个例子中,对buffers进行过滤后,load在pdv中observation只有2条了,因此keep的计算量只有2次。基于这个计算量上的差异,后者的效率要高于前者。
已有 1 人评分经验 论坛币 学术水平 热心指数 收起 理由
crackman + 100 + 100 + 1 + 1 好的意见建议

总评分: 经验 + 100  论坛币 + 100  学术水平 + 1  热心指数 + 1   查看全部评分

17
yatming 发表于 2010-5-10 23:27:48
补充了一下,有些是自己的理解,欢饮拍砖。

18
fxf258 发表于 2010-5-11 08:28:30
学习了,非常好,有帮助有启发!

19
yzzhang 发表于 2010-5-11 09:21:53
回答的太好了!^_^
想接着问下,
1数据从硬盘到buffer,2在buffer进行筛选,3从buffer读入pdv,4对读入pdv的相关进行运算,5从pdv输出到硬盘
想问下上面几个步骤中1 3 5这三步花费时间占比高吗?
还有sas日志中cpu时间和实际时间差别是什么?

非常感谢继续有精彩的回复!!

16# yatming

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-27 07:23