SAS、proc summary 中哪些统计数据计算得更快?
Which statistics is calculated faster in SAS, proc summary?
我需要一个理论上的答案。
假设您有一个包含 15 亿行的 table(table 是使用 DB2-Blu 创建的基于列的)。
您正在使用 SAS,您将通过使用 Proc Summary
像 min/max/mean 值、标准偏差值和 percentile-10、percentile-90 通过您的同龄人做一些统计。
例如,您有 30.000 个对等组,每个对等组中有 50.000 个值(总计 15 亿个值)。
另一种情况下,您有 300 万个对等组,每个对等组中也有 50 个值。所以你又得到了 15 亿个值。
如果你有更少的同龄人群体但每个同龄人群体中有更多的价值,它会更快吗?或者它会随着更多的同龄人组而更快但每个同龄人组中的价值更少。
我可以测试第一个案例(30.000 个对等组和每个对等组 50.000 个值),大约需要 16 分钟。但是我无法测试第二种情况。
如果我有 300 万对等组并且每个对等组有 50 个值,你能写出 运行 时间的大概预测吗?
问题多了一个维度。如果我改用 Proc SQL
做这些统计会更快吗?
示例代码如下:
proc summary data = table_blu missing chartype;
class var1 var2; /* Var1 and var2 are toghether peer-group */
var values;
output out = stattable(rename = (_type_ = type) drop = _freq_)
n=n min=min max=max mean=mean std=std q1=q1 q3=q3 p10=p10 p90=p90 p95=p95
;
run;
所以这里有很多事情需要考虑。
第一点并且很可能是性能方面最大的一点是将数据从 DB2 导入 SAS。 (我假设这不是 SAS 的数据库实例——如果是的话请纠正我)。这是一个很大的 table 并且通过网络移动它需要时间。因此,如果您可以使用 SQL 语句在 DB2 中计算所有这些统计数据,那可能是您最快的选择。
因此假设您已将 table 下载到 SAS 服务器:
按 CLASS
变量排序的 table 比未排序的 table 处理起来要快得多。如果 SAS 知道 table 已排序,它就不必扫描 table 的记录以进入组,它可以进行块读取而不是 运行dom IO。
如果 table 未排序,则组数越大,则必须进行的 table 次扫描越多。
关键是,从 HD 获取数据到 CPU 的速度在未排序的过程中将是最重要的。
从那里开始,您将进入内存和 cpu 问题。 PROC SUMMARY 是多线程的,SAS 一次会读取 N 组。如果组大小适合为该线程分配的内存,则不会有问题。如果组大小太大,则 SAS 将不得不分页。
我将问题缩小到 15M 行示例:
%let grps=3000;
%let pergrp=5000;
未排序:
NOTE: There were 15000000 observations read from the data set
WORK.TEST.
NOTE: The data set WORK.SUMMARY has 3001 observations and 9
variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
real time 20.88 seconds
cpu time 31.71 seconds
已排序:
NOTE: There were 15000000 observations read from the data set
WORK.TEST.
NOTE: The data set WORK.SUMMARY has 3001 observations and 9
variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
real time 5.44 seconds
cpu time 11.26 seconds
=============================
%let grps=300000;
%let pergrp=50;
未排序:
NOTE: There were 15000000 observations read from the data set
WORK.TEST.
NOTE: The data set WORK.SUMMARY has 300001 observations and 9
variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
real time 19.26 seconds
cpu time 41.35 seconds
已排序:
NOTE: There were 15000000 observations read from the data set
WORK.TEST.
NOTE: The data set WORK.SUMMARY has 300001 observations and 9
variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
real time 5.43 seconds
cpu time 10.09 seconds
我运行这几次和运行次差不多。排序时间大致相等,而且速度更快。
组数越多/每组越少,未排序速度越快,但查看总 CPU 使用率,它更高。我的笔记本电脑有一个非常快的 SSD,所以 IO 可能不是限制因素——HD 能够跟上多核 CPU 的需求。在 HD 较慢的系统上,总 运行 次可能不同。
最后,这在很大程度上取决于数据的结构以及您的服务器和数据库的具体情况。
不是理论上的答案,但仍然与 IMO 相关...
要在大型表上加快 proc summary
的速度,请将 / groupinternal
选项添加到 class 语句中。当然,假设您不希望在分组之前格式化变量。
例如:
class age / groupinternal;
这告诉 SAS 在计算 class 将值分组到什么之前不需要对值应用格式。即使您没有明确指定,每个值都将应用一种格式。这在小表上没有太大区别,但在大表上却可以。
通过这个简单的测试,它将时间从我机器上的 60 秒减少到 40 秒 (YMMV):
data test;
set sashelp.class;
do i = 1 to 10000000;
output;
end;
run;
proc summary data=test noprint nway missing;
class age / groupinternal;
var height;
output out=smry mean=;
run;
我需要一个理论上的答案。
假设您有一个包含 15 亿行的 table(table 是使用 DB2-Blu 创建的基于列的)。
您正在使用 SAS,您将通过使用 Proc Summary
像 min/max/mean 值、标准偏差值和 percentile-10、percentile-90 通过您的同龄人做一些统计。
例如,您有 30.000 个对等组,每个对等组中有 50.000 个值(总计 15 亿个值)。
另一种情况下,您有 300 万个对等组,每个对等组中也有 50 个值。所以你又得到了 15 亿个值。
如果你有更少的同龄人群体但每个同龄人群体中有更多的价值,它会更快吗?或者它会随着更多的同龄人组而更快但每个同龄人组中的价值更少。
我可以测试第一个案例(30.000 个对等组和每个对等组 50.000 个值),大约需要 16 分钟。但是我无法测试第二种情况。
如果我有 300 万对等组并且每个对等组有 50 个值,你能写出 运行 时间的大概预测吗?
问题多了一个维度。如果我改用 Proc SQL
做这些统计会更快吗?
示例代码如下:
proc summary data = table_blu missing chartype;
class var1 var2; /* Var1 and var2 are toghether peer-group */
var values;
output out = stattable(rename = (_type_ = type) drop = _freq_)
n=n min=min max=max mean=mean std=std q1=q1 q3=q3 p10=p10 p90=p90 p95=p95
;
run;
所以这里有很多事情需要考虑。
第一点并且很可能是性能方面最大的一点是将数据从 DB2 导入 SAS。 (我假设这不是 SAS 的数据库实例——如果是的话请纠正我)。这是一个很大的 table 并且通过网络移动它需要时间。因此,如果您可以使用 SQL 语句在 DB2 中计算所有这些统计数据,那可能是您最快的选择。
因此假设您已将 table 下载到 SAS 服务器:
按 CLASS
变量排序的 table 比未排序的 table 处理起来要快得多。如果 SAS 知道 table 已排序,它就不必扫描 table 的记录以进入组,它可以进行块读取而不是 运行dom IO。
如果 table 未排序,则组数越大,则必须进行的 table 次扫描越多。
关键是,从 HD 获取数据到 CPU 的速度在未排序的过程中将是最重要的。
从那里开始,您将进入内存和 cpu 问题。 PROC SUMMARY 是多线程的,SAS 一次会读取 N 组。如果组大小适合为该线程分配的内存,则不会有问题。如果组大小太大,则 SAS 将不得不分页。
我将问题缩小到 15M 行示例:
%let grps=3000;
%let pergrp=5000;
未排序:
NOTE: There were 15000000 observations read from the data set
WORK.TEST.
NOTE: The data set WORK.SUMMARY has 3001 observations and 9
variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
real time 20.88 seconds
cpu time 31.71 seconds
已排序:
NOTE: There were 15000000 observations read from the data set
WORK.TEST.
NOTE: The data set WORK.SUMMARY has 3001 observations and 9
variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
real time 5.44 seconds
cpu time 11.26 seconds
=============================
%let grps=300000;
%let pergrp=50;
未排序:
NOTE: There were 15000000 observations read from the data set
WORK.TEST.
NOTE: The data set WORK.SUMMARY has 300001 observations and 9
variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
real time 19.26 seconds
cpu time 41.35 seconds
已排序:
NOTE: There were 15000000 observations read from the data set
WORK.TEST.
NOTE: The data set WORK.SUMMARY has 300001 observations and 9
variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
real time 5.43 seconds
cpu time 10.09 seconds
我运行这几次和运行次差不多。排序时间大致相等,而且速度更快。
组数越多/每组越少,未排序速度越快,但查看总 CPU 使用率,它更高。我的笔记本电脑有一个非常快的 SSD,所以 IO 可能不是限制因素——HD 能够跟上多核 CPU 的需求。在 HD 较慢的系统上,总 运行 次可能不同。
最后,这在很大程度上取决于数据的结构以及您的服务器和数据库的具体情况。
不是理论上的答案,但仍然与 IMO 相关...
要在大型表上加快 proc summary
的速度,请将 / groupinternal
选项添加到 class 语句中。当然,假设您不希望在分组之前格式化变量。
例如:
class age / groupinternal;
这告诉 SAS 在计算 class 将值分组到什么之前不需要对值应用格式。即使您没有明确指定,每个值都将应用一种格式。这在小表上没有太大区别,但在大表上却可以。
通过这个简单的测试,它将时间从我机器上的 60 秒减少到 40 秒 (YMMV):
data test;
set sashelp.class;
do i = 1 to 10000000;
output;
end;
run;
proc summary data=test noprint nway missing;
class age / groupinternal;
var height;
output out=smry mean=;
run;