2009-04-16 23 views
6

Hasta donde yo sé, las cadenas son inmutables en Delphi. Yo como que entiendo que significa que si usted hace:¿Las cadenas de Delphi son inmutables?

string1 := 'Hello'; 
string1 := string1 + " World"; 

primera cadena se destruye y se obtiene una referencia a una nueva cadena "Hola Mundo".

Pero, ¿qué ocurre si tienes la misma cadena en diferentes lugares de tu código?

Tengo un hash de cadena asignado para identificar varias variables, por lo que, por ejemplo, un "cambio" se identifica mediante un valor hash de las propiedades de ese cambio. De esa manera, es fácil para mí verificar los "cambios" de igualdad.

Ahora, cada hash se calcula por separado (no todas las propiedades se tienen en cuenta para que las instancias separadas puedan ser iguales incluso si difieren en algunos valores).

La pregunta es, ¿cómo maneja Delphi esas cadenas? Si calculo para separar hashes a la misma cadena de 10 bytes de longitud, ¿qué obtengo? ¿Dos bloques de memoria de 10 bytes o dos referencias al mismo bloque de memoria?

Aclaración: Un cambio se compone de algunas propiedades leídas de la base de datos y generadas por un hilo individual. La clase TChange tiene un método GetHash que calcula un hash basado en algunos de los valores (pero no todos) que resultan en una cadena. Ahora, otros subprocesos reciben el cambio y tienen que compararlo con los cambios procesados ​​previamente para que no procesen el mismo cambio (lógico). De ahí el hash y, como tienen instancias separadas, se calculan dos cadenas diferentes. Estoy tratando de determinar si sería una mejora real cambiar de cadena a algo así como un hash de 128 bits o simplemente voy a perder el tiempo.

Editar: La versión de Delphi Delphi es 7,0

Respuesta

20

Las cadenas de Delphi son copiadas en escritura. Si modifica una cadena (sin utilizar trucos de puntero o técnicas similares para engañar al compilador), no se verán afectadas otras referencias a la misma cadena.

Las cadenas de Delphi no están internados. Si crea la misma cadena a partir de dos secciones separadas de código, no compartirán el mismo almacén de respaldo; los mismos datos se almacenarán dos veces.

+0

Una vez tuve un problema con las manipulaciones de cadenas en una DLL, y después de un largo búsqueda Descubrí que IsMultiThread se configuró en falso. Se declara en System.pas y se usa al modificar el recuento y el almacenamiento de referencias de cadenas. Configurarlo como verdadero en mi sección de inicialización resolvió mi problema. –

+0

Stijn: el mecanismo de recuento de referencias utiliza instrucciones de incremento y decremento de bloqueo de bus para que sean seguros para subprocesamiento múltiple. Sin embargo, estos son más lentos de lo normal inc y dec. IsMultiThread se establece mediante la creación de un hilo desde dentro de Delphi. Por supuesto, si creas un hilo fuera de Delphi o si usas la API subyacente sin procesar, no lo sabrá. –

0

La versión de Delphi puede ser importante conocer. El buen viejo Delphi BCL maneja cadenas como copy-on-write, lo que básicamente significa que se crea una nueva instancia cuando se cambia algo en la cadena. Entonces sí, son más o menos inmutables.

+1

La cosa es que ... ¿Qué pasa si me generan la misma cadena a partir de dos secciones diferentes de código? Eso no es copiar al escribir ... –

+0

BCL? Creo que te refieres a RTL. (No quiso decir VCL, el VCL no controla en absoluto cómo funcionan las cadenas). –

+0

@Jorge: Generar una cadena con los mismos contenidos no la convierte en la misma referencia. Pero esto no tiene nada que ver con la inmutabilidad. @Rob: Bueno, BCL significa Base Class Library, la RTL es una de esas bestias ...;) – Lucero

4

Las cadenas de Delphi no son inmutables (try: string1 [2]: = 'a') pero están contadas por referencia y copy-on-write.

Las consecuencias para sus hashes no son claras, que tendrá que detalle la forma en que se almacenan etc.

Pero un hash sólo deben depender de los contenidos de una cadena, no en la forma en que se almacena. Eso hace que toda la pregunta quede muda. A menos que puedas explicarlo mejor.

+0

En realidad, un hash puede verse como un resumen de cierta información, cualquier información. Eso es básicamente lo que estoy haciendo, resumiendo los valores dentro de la clase en un hash, que resulta ser una cadena (¡el hash, no los valores!) –

Cuestiones relacionadas