close Warning: Can't synchronize with repository "(default)" (/var/svn/tolp does not appear to be a Subversion repository.). Look in the Trac log for more information.

Opened 14 years ago

Last modified 14 years ago

#1061 accepted defect

GetDir is slow

Reported by: Jorge Owned by: Jorge
Priority: highest Milestone: Mantainance
Component: System Version: 2.0.1
Severity: critical Keywords:
Cc: pgea@…

Description

We have realized that GetDir is behaving quite slow when the path is located remotely and the amount of files ia around 100. Below is an implementation based on OS commands that is faster than the builtin GetDir.

//////////////////////////////////////////////////////////////////////////////
Set GetDir_Files(Text path)
//////////////////////////////////////////////////////////////////////////////
{
  // Versión de GetDir(...)[1] más rápida. Para Windows.
  If(OSName=="WINDOWS" & True, {
    Text WriteFile(TmpDir<<"dirbf.bat", "@echo off\ndir %1 /B /A-D");
    Real WinSystem(Qt(TmpDir<<"dirbf.bat")<<" "<<Qt(path)<<" > "
      <<Qt(TmpDir<<"dirbf.dat"), 0, 1);
    Set dir = Tokenizer(ReadFile(TmpDir<<"dirbf.dat"), "\n");
    Real FileDelete(TmpDir<<"dirbf.bat");
    Real FileDelete(TmpDir<<"dirbf.dat");
    Select(dir, TextLength)
  }, GetDir(path)[1])
};


Text path = "M:/TfnEsp/MeMoCC/repository/repMovil/Estimations/";
Real t1 = Copy(Time);
Set GetDir_Files(path);
Real t2 = Copy(Time);
Set GetDir(path)[1];
Real t3 = Copy(Time);
WriteLn("Método1: "<<(Real t2-t1)<<"s\nMétodo2: "<<(Real t3-t2)<<"s");

Change History (2)

comment:1 Changed 14 years ago by Jorge

Status: newaccepted

comment:2 Changed 14 years ago by Pedro Gea

Tengo otro método GetDir_Files, menos rápido que el anterior, pero igualmente mucho más rápido que GetDir. Usa glob de Tcl y probablemente está más libre de errores que en este anterior basado en la escritura de un archivo temporal.

Adjunto el código a continuación:

//////////////////////////////////////////////////////////////////////////////
Set GetDir_Files_Tcl(Text path)
//////////////////////////////////////////////////////////////////////////////
{
  Text pathm = Replace(path, "\\", "/");
  Text pathm := pathm<<If(TextSub(pathm,-1,-1)=="/", "", "/");
  EvalSet(Eval("SetOfText("<<TextSub(Tcl_Eval("
    set files [glob -type f -directory {"<<pathm<<"} *]
    set files2 {}
    foreach file $files {
      lappend files2 \\\"$file\\\",
    }
    join $files2
  ")[1],1,-2)<<")"), Text (Text filename) {
    TextSub(filename, TextLength(pathm)+1, -1)
  })
};

Nótese que el método TextSub es un método implementado en MMS que resulta útil porque salva la ambigüedad de la función Sub de TOL en la que se basa y además permite indicar posiciones negativas (contando desde el final al principio).
Adjunto el código aquí también por si alguien quiere usarlo:

Text TextSub(Text text, Real ini, Real end) {
  Sub(text, If(ini<0,TextLength(text)+1+ini,ini),
    If(end<0,TextLength(text)+1+end,end) ) 
};
Note: See TracTickets for help on using tickets.