<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Ich habe ein JMP-Skript, um den Benutzer zur Eingabe eines Verzeichnisses aufzufordern und dann aus diesem Verzeichnis heraus nach bestimmten Dateitypen zu filtern.Mein Problem ist, dass der Filtervorgang oft länger dauert als nur das Abrufen der Dateien.Wenn die Anzahl der Dateien groß ist (>100.000 Dateien), kann die Gesamtzeit zum Sammeln und Filtern von Dateien mehr als 30 Minuten betragen.Gibt es eine schnellere oder effizientere Möglichkeit, dies zu tun?Ich verwende JMP11. Danke!
// Beispiel.
Namen standardmäßig hier( 1 );
dir = Verzeichnis auswählen( "Verzeichnis auswählen", "/C:/Programme/SAS/" );
t1 = Tick Seconds();
files = Dateien im Verzeichnis (dir, rekursiv);
t2 = Tick Seconds();
t_getfiles = t2 - t1;
n_getfiles = N Items( files );
t3 = Tick Seconds();
For( i = N Items( files ), i >= 1, i--,
If( !Ends With( Dateien , ".jmp"),
Entfernen aus (Dateien, i)
)
);
t4 = Tick Seconds();
t_filterfiles = t4 - t3;
n_filterfiles = N Items( files );
Show( t_getfiles, n_getfiles, t_filterfiles, n_filterfiles );
Danke Craige, das funktioniert großartig!
Das erste Beispiel ist in JMP 12 viel schneller (ähnliche Geschwindigkeit wie das Datentabellenbeispiel); Es scheint, dass es in JMP 11 immer noch ein gewisses N^2-Verhalten zeigt.
Ja, überarbeiten Sie die Filterschleife, um das N^2-Verhalten zu entfernen.JSL { listet } Zugriffselemente auf, indem es von vorne beginnt.Sie haben hinten angefangen, um zu verhindern, dass die gelöschten Elemente die Indizierung durcheinander bringen.Das führt so ziemlich zum ungünstigsten Zeitverhalten für die Manipulation der Liste, indem i Elemente durchlaufen werden, um das i-te Element zu erreichen.Hier ist eine überarbeitete Version, die das vorderste Element aus der Liste der Dateien entfernt, es überprüft und es als vorderstes Element der gefilterten Liste einfügt.
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;
Ungefähr 5 Minuten.
Eine andere Idee: Sie können eine Datentabelle wie folgt laden:
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;
Ungefähr 5 Sekunden.Das <