<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />我有一个 JMP 脚本来提示用户输入目录,然后从该目录中过滤特定的文件类型。我的问题是过滤过程通常比获取文件花费的时间更长。如果文件数量较大(>100,000 个文件),则收集和过滤文件的总时间可能会超过 30 分钟。有没有更快或更有效的方法来做到这一点?我正在使用 JMP11。谢谢!
// 例子。
名称默认为此处( 1 );
dir = 选择目录( "选择目录", "/C:/Program Files/SAS/" );
t1 = 滴答秒();
文件=目录中的文件(dir,递归);
t2 = 滴答秒();
t_getfiles = t2 - t1;
n_getfiles = N 个项目( 文件 );
t3 = 滴答秒();
For( i = N 个项目( 文件 ), i >= 1, i--,
If( !Ends With( 文件,“.jmp”),
从(文件,i)中删除
)
);
t4 = 滴答秒();
t_filterfiles = t4 - t3;
n_filterfiles = N 个项目(文件);
显示( t_getfiles, n_getfiles, t_filterfiles, n_filterfiles );
第一个示例在 JMP 12 中要快得多(与数据表示例的速度相似);它似乎仍在 JMP 11 中表现出一些 N^2 行为。
是的,重新设计过滤循环以删除 N^2 行为。JSL {lists} 从前面开始访问元素。您从后面开始,以防止删除的元素弄乱索引。这导致了操作列表时几乎最坏情况的时间行为,遍历 i 个元素以到达第 i 个元素。这是一个重新设计的版本,它从文件列表中删除最前面的元素,检查它,然后将其插入作为过滤列表的最前面的元素。
dir = "c:\";
t1 = Tick Seconds();
files = Files In Directory( dir, Recursive );
t2 = Tick Seconds();
t_getfiles = t2 - t1;
n_getfiles = N Items( files );
filteredFiles = {};
t3 = Tick Seconds();
while( (testname = Remove From( files, 1 )) != {},
If( Ends With( testname[1], ".jmp" ),
insertinto(filteredFiles,testname,1);
)
);
t4 = Tick Seconds();
t_filterfiles = t4 - t3;
n_filterfiles = N Items( filteredFiles );
Show( t_getfiles, n_getfiles, t_filterfiles, n_filterfiles );
t_getfiles = 4.0333333333333;
n_getfiles = 171630;
t_filterfiles = 258.5;
n_filterfiles = 975;
大约5分钟。
另一个想法:您可以像这样加载数据表:
dir = "c:\";
t1 = Tick Seconds();
files = Files In Directory( dir, Recursive );
t2 = Tick Seconds();
t_getfiles = t2 - t1;
n_getfiles = N Items( files );
t3 = tickseconds();
dt = New Table( "directory",
Add Rows( 0 ),
New Column( "filename", Character, Nominal, Set Values( files ) ),
New Column( "isTable",
Numeric,
Continuous,
Format( "Best", 12 ),
Formula( Ends With( :filename, ".jmp" ) )
)
);
dt<
dt<
dtFiltered = dt<
t4=tickseconds();
t_filterfiles = t4 - t3;
n_filterfiles = N rows( dtFiltered );
Show( t_getfiles, n_getfiles, t_filterfiles, n_filterfiles );
t_getfiles = 4.01666666666642;
n_getfiles = 171635;
t_filterfiles = 0.716666666666697;
n_filterfiles = 975;
大约5秒。<