Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Tstrings Delphi 2007 (https://www.clubdelphi.com/foros/showthread.php?t=86680)

JaviMarciano 15-09-2014 22:51:56

Tstrings Delphi 2007
 
hay una manera de hacer esto más eficiente:
necesito concatenar cada item de un Tstrings en en una cadena separado por espacios

Código Delphi [-]
function TOracle.GetStatement(StatementLines: TStrings): string;
var
  I: Integer;
  Statement: string;
begin
  Statement := '';
  for i := 0 to StatementLines.Count - 1 do
  begin
    Statement := Statement + ' ' + Trim(StatementLines[i]);
  end;
    Result := TrimLeft(Statement);
end;
es para delphi 2007

ecfisa 15-09-2014 23:08:21

Hola JaviMarciano.

Podes ahorrarte la variable Statement usando la variable implícita Result,
Código Delphi [-]
function GetStatement(StatementLines: TStrings): string;
var
  i: Integer;
begin
  Result := '';
  for i := 0 to StatementLines.Count - 1 do
    Result := Result + Trim(StatementLines[i]) + ' ';
  SetLength(Result, Length(Result)-1);
end;


Saludos :)

Neftali [Germán.Estévez] 16-09-2014 10:51:13

Una alternativa podría ser algo así, pero tendrás que probar si realmente es más eficiente:

Código Delphi [-]
  Result := AnsiReplaceText(StatementLines.Text, sLineBreak, ' ');

Y añadir al uses la unit StrUtils.

engranaje 16-09-2014 14:29:36

Si no ando desencaminado y como para lo único que utilizas StatementLines es para obtener información igual es mas eficiente declararla como constante, habría que comprobarlo.
Código Delphi [-]
function GetStatement(const StatementLines: TStrings): string; 
var   
  i: Integer; 
begin   
  Result := '';   
  for i := 0 to StatementLines.Count - 1 do
    Result := Result + Trim(StatementLines[i]) + ' ';   
  SetLength(Result, Length(Result)-1); 
end;

ecfisa 16-09-2014 16:57:35

Muy buena la opción de Neftali ^\||/ (no me acordé de ella) a la que se le podría sumar ExtractStrings de la unit Classes.

Para salir de dudas sobre la eficiencia de usar una u otra alternativa, hice una prueba sobre un archivo de texto de 22350 líneas con este código:
Código Delphi [-]
...
uses StrUtils;

var
  frec, ini, fin: Int64;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Lines.LoadFromFile('C:\PRUEBA.TXT');
  Caption:= Format('Nro lineas: %d', [Memo1.Lines.Count[);
  QueryPerformanceFrequency(frec);
end;

// Usando for para concatenar
function Concat1(Lineas: TStrings): string;
var
  i: Integer;
begin
  Result := '';
  Lineas.BeginUpdate;
  try
    for i := 0 to Lineas.Count - 1 do
      Result := Result + Trim(Lineas[i]) + ' ';
    SetLength(Result, Length(Result)-1);
  finally
    Lineas.EndUpdate;
  end;
end;

// Usando AnsiReplaceText para concatenar
function Concat2(Lineas: TStrings): string;
begin
  Result:= AnsiReplaceText(Lineas.Text, sLineBreak, ' ');
end;

procedure TForm1.btnForClick(Sender: TObject);
begin
  Memo2.Clear;
  QueryPerformanceCounter(ini);
  Memo2.Text:= Concat1(Memo1.Lines);
  QueryPerformanceCounter(fin);
  Label1.Caption:= FormatFloat('0, µs.', (fin - ini) * 1000000 div frec);
end;

procedure TForm1.btnExtClick(Sender: TObject);
begin
  Memo2.Clear;
  QueryPerformanceCounter(ini);
  Memo2.Text:= Concat2(Memo1.Lines);
  QueryPerformanceCounter(fin);
  Label2.Caption:= FormatFloat('0, µs.', (fin - ini) * 1000000 div frec);
end;
(Mientras escribía la prueba recordé agreguar EnableControls y DisiableControls para mejorar la performance.)

El resultado promedio de 3 mediciones:
  • Procedimiento Concat1: 1.411.396 ms
  • Procedimiento Concat2: 7.415.044 ms

La balanza se inclina a recorrer el TStrings con un for y creo que es debido a que AnsiReplaceText debe realizar comprobaciones adicionales para lograr su gran ductilidad de uso.

Saludos :)


La franja horaria es GMT +2. Ahora son las 22:44:14.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi