technologies systems software mexico empresa diesel brasil autopartes delphi

systems - Delphi StringBuilder



delphi technologies (7)

¿Existe en Delphi algo como Java o C # StringBuilder? O Delphi no necesita StringBuilder y s := s + ''some string''; Es buena expresión (principalmente en for, while bucles).


Delphi no " REQUIERE " una clase de generador de cadenas, pero se proporciona una para Delphi 2009 si así lo desea. Tu ejemplo de s: = s + ''alguna cadena''; es un método típico de concatinar cadenas y se ha utilizado en Pascal / Delphi durante las últimas décadas sin ningún problema significativo.


El TStringBuilder mencionado es el camino a seguir. En su caso específico, la concatenación puede estar bien, pero siempre intentaría la alternativa de todos modos.

Estoy creando un archivo xhtml de contenido del cuerpo de EPUB en la memoria (Delphi XE) y tardé tanto en producirlo que nunca lo dejé terminar (unos 5 minutos más antes de abandonarlo). Este es un ejemplo de la vida real que combina alrededor de 800,000 caracteres de texto. Tomar el mismo código EXACTO y reemplazar directamente las sentencias de estilo s: = s + '''' con las sentencias TStringBuilder.Append lo redujo a alrededor de 3 segundos . Para reiterar, no hubo cambios lógicos más allá de un cambio de la concatenación.


En Delphis anterior, puedes usar el HVStringBuilder de Hallvard Vassbotn. No pude encontrar las fuentes en su blog, pero puede buscarlas en el árbol de fuentes de OmniThreadLibrary , por ejemplo (necesitará los archivos HVStringBuilder.pas y HVStringData.pas).


Estoy realmente sorprendido de que nadie mencione en ninguno de los comentarios o ejemplos que puede indicar a TStringBuilder que preasigne un búfer apropiado para la tarea durante la creación de instancias. En otras palabras, si puede obtener una estimación simple de la cantidad de memoria que probablemente necesitará, rellene ese bit un poco y use ese valor para crear una instancia de TStringBuilder, evitará las reasignaciones de memoria que ralentizan la concatenación de cadenas simples a un rastreo:

buff := TStringBuilder.Create( tmpEstimatedSize );

Utilizo TStringBuilder regularmente en el nuevo código y para optimizar el código antiguo, y el ahorro de la CPU al construir cadenas grandes incrementalmente es dramático. Ahora para ser transparente, si solo tengo un puñado de cadenas para concatenar, no me molesto con TStringBuilder. Pero si estoy, por ejemplo, serializando lo que potencialmente podría ser una gran cantidad de datos, TStringBuilder es la solución obvia.


He enumerado algunos buenos recursos en las cadenas de Delphi a continuación.

Como dijo alguien más, la concatenación simple que usa el operador ''+'' con los tipos de cadena de propósito general es tan rápida como usar TStringbuilder (al menos para operaciones de la forma: ''s: = s + [....]''). No sé si es verdad o no, pero el rendimiento es al menos lo suficientemente cercano como [1], a continuación, afirma que "la concatenación de cadenas en Delphi es tan rápida que la nueva clase de StringBuilder optimizada en Delphi 2009 no puede superarla". Esto se debe a que las cadenas se modifican en su lugar y Delphi transparenty asigna más memoria para la cadena base si es necesario, en lugar de realizar una operación de copia en escritura de todos los datos a una nueva ubicación en la memoria.

[1] http://blog.marcocantu.com/blog/delphi_super_duper_strings.html

[2] http://conferences.codegear.com/he/article/32120

[3] http://www.codexterity.com/delphistrings.htm

[4] http://www.monien.net/blog/index.php/2008/10/delphi-2009-tstringbuilder/


Sí, Delphi ofrece TStringBuilder (desde la versión 2009):

procedure TestStringBuilder; var I: Integer; StringBuilder: TStringBuilder; begin StringBuilder := TStringBuilder.Create; try for I := 1 to 10 do begin StringBuilder.Append(''a string ''); StringBuilder.Append(66); //add an integer StringBuilder.Append(sLineBreak); //add new line end; OutputWriteLine(''Final string builder length: '' + IntToStr(StringBuilder.Length)); finally StringBuilder.Free; end; end;

Y si, tienes razón. s := s + ''text''; no es realmente más lento que usar TStringBuilder.


s: = s + ''alguna cadena'' podría ser terriblemente lenta si lo haces en un bucle debido a la asignación de memoria involucrada. ¡He realizado algunas pruebas que muestran que la memoria de preasignación podría ser 132 veces más rápida (SÍ, LEA ESTOY BIEN) más rápido!

El código es más complejo que el simple s: = s + algo:

marker:= 1; CurBuffLen:= 0; for i:= 1 to Length(FileBody) DO begin if i > CurBuffLen then begin SetLength(s, CurBuffLen+ BuffSize); CurBuffLen:= Length(s) end; s[marker]:= FileBody[i]; Inc(marker); end;

pero es mucho más rápido.

Vea mi respuesta aquí para obtener detalles: ¿ Cuándo y por qué debo usar TStringBuilder?

Nota: mi código está optimizado para

s: = s + c

donde c es un char, pero puedes adaptarlo fácilmente

para s: = s + ''alguna cadena''

.