En informática, el internado de cadenas es un método para almacenar solo una copia de cada valor de cadena distinto, que debe ser inmutable . [ 1 ] El internado de cadenas hace que algunas tareas de procesamiento de cadenas sean más eficientes en tiempo o espacio, a costa de requerir más tiempo cuando la cadena se crea o se interna. Los valores distintos se almacenan en un grupo de internado de cadenas .
La única copia de cada cadena se llama su interna y normalmente se busca mediante un método de la clase string, por ejemplo String.intern() [ 2 ] en Java . Todas las cadenas constantes en tiempo de compilación en Java se internan automáticamente usando este método. [ 3 ]
La internación de cadenas es compatible con algunos lenguajes de programación orientados a objetos modernos , incluidos Java, Python , PHP (desde la versión 5.4), Lua [ 4 ] y los lenguajes .NET . [ 5 ] Lisp , Scheme , Julia , Ruby y Smalltalk se encuentran entre los lenguajes con un tipo de símbolo que son básicamente cadenas internadas. La biblioteca del Standard ML de Nueva Jersey contiene un tipo que hace lo mismo. Los selectores de Objective-C , que se utilizan principalmente como nombres de métodos, son cadenas internadas.atom
Se pueden internar objetos distintos de las cadenas. Por ejemplo, en Java, cuando los valores primitivos se encapsulan en un objeto contenedor , ciertos valores (cualquier boolean, cualquier byte, cualquier charentre 0 y 127, y cualquier shorto intentre -128 y 127) se internan, y se garantiza que dos conversiones de encapsulado de uno de estos valores darán como resultado el mismo objeto. [ 6 ]
Historia
Lisp introdujo la noción de cadenas internadas para sus símbolos . Históricamente, la estructura de datos utilizada como grupo de cadenas internadas se denominaba oblist (cuando se implementaba como una lista enlazada ) o obarray (cuando se implementaba como un array).
Los dialectos modernos de Lisp suelen distinguir entre símbolos y cadenas de caracteres; al internar una cadena, se devuelve un símbolo existente o se crea uno nuevo, cuyo nombre coincide con el de dicha cadena. Los símbolos suelen tener propiedades adicionales que las cadenas no poseen, como el almacenamiento de valores asociados o la asignación de espacios de nombres. Esta distinción también resulta útil para evitar comparaciones accidentales entre cadenas internadas y cadenas que no necesariamente lo están, lo que podría provocar fallos intermitentes según los patrones de uso.
Motivación
El internado de cadenas acelera las comparaciones de cadenas, que a veces representan un cuello de botella en el rendimiento de aplicaciones (como compiladores y entornos de ejecución de lenguajes de programación dinámicos ) que dependen en gran medida de matrices asociativas con claves de cadena para buscar los atributos y métodos de un objeto. Sin internado, comparar dos cadenas distintas puede implicar examinar cada carácter de ambas. Esto es lento por varias razones: es inherentemente O(n) en la longitud de las cadenas; normalmente requiere lecturas de varias regiones de memoria , lo que consume tiempo; y las lecturas llenan la caché del procesador, lo que significa que hay menos caché disponible para otras necesidades. Con cadenas internadas, una simple prueba de identidad de objeto es suficiente después de la operación de internado original; esto se implementa normalmente como una prueba de igualdad de punteros, normalmente solo una instrucción de máquina sin ninguna referencia a memoria.
El almacenamiento interno de cadenas también reduce el uso de memoria si existen muchas instancias del mismo valor de cadena; por ejemplo, si se lee desde una red o desde el almacenamiento . Dichas cadenas pueden incluir números mágicos o información de protocolo de red . Por ejemplo, los analizadores XML pueden almacenar internamente los nombres de las etiquetas y los atributos para ahorrar memoria. La transferencia de objetos en red a través de flujos de objetos de serialización Java RMI puede transferir cadenas almacenadas internamente de forma más eficiente, ya que el identificador del objeto String se utiliza en lugar de objetos duplicados durante la serialización. [ 7 ]
Asuntos
Multihilo
Si las cadenas internadas no son inmutables, una fuente de inconvenientes es que la internación de cadenas puede ser problemática cuando se combina con multihilo . En muchos sistemas, las internas de cadenas deben ser globales en todos los hilos dentro de un espacio de direcciones (o en cualquier contexto que pueda compartir punteros), por lo que el o los grupos de internas son recursos globales que deben sincronizarse para un acceso concurrente seguro. Si bien esto solo afecta la creación de cadenas (donde el grupo de internas debe verificarse y modificarse si es necesario), y se puede usar el bloqueo de doble verificación en plataformas donde esto es una optimización segura, la necesidad de exclusión mutua al modificar el grupo de internas puede ser costosa. [ 8 ]
La contención también puede reducirse dividiendo el espacio de cadenas en varios grupos, que pueden sincronizarse independientemente unos de otros.
Recuperación de cadenas internas no utilizadas
Muchas implementaciones de cadenas internadas no intentan recuperar (manual o automáticamente) las cadenas que ya no se utilizan. Para aplicaciones donde el número de cadenas internadas es pequeño o fijo, o que tienen una vida útil corta, la pérdida de recursos del sistema puede ser tolerable. Pero para sistemas de larga duración donde se crean grandes cantidades de cadenas internadas en tiempo de ejecución, puede surgir la necesidad de recuperar las internadas no utilizadas. Esta tarea puede ser gestionada por un recolector de basura , aunque para que esto funcione correctamente, se deben almacenar referencias débiles a las cadenas internadas en el grupo de internadas.
Véase también
Referencias
- ↑ "String.Intern Method (String)" . Microsoft Developer Network . Consultado el 25 de marzo de 2017 .
- ↑
String.intern() - ↑ "Capítulo 15. Expresiones" . docs.oracle.com . Consultado el 30 de enero de 2019 .
- ↑ "wiki de usuarios de lua: objetos inmutables" . lua-users.org . Consultado el 30 de enero de 2019 .
- ↑ rpetrusha. "Clase String (System)" . docs.microsoft.com . Consultado el 30 de enero de 2019 .
- ↑ "Capítulo 5. Conversiones y promociones" . docs.oracle.com . Consultado el 30 de enero de 2019 .
- ↑ "Especificación de serialización de objetos Java: 1 - Arquitectura del sistema" . docs.oracle.com . Consultado el 30 de enero de 2019 .
- ↑ "String.intern en Java 6, 7 y 8: acceso multihilo" . java-performance.info . 3 de septiembre de 2013. Consultado el 30 de enero de 2019 .
Enlaces externos
- Clase String de Visual J#
- Clase String de .NET
- Biblioteca Java Guava - Interner - String.intern no permanente y admite otros tipos inmutables con implementaciones de referencia débil y fuerte.
- Comprender el método intern() de Java para cadenas de caracteres
- Optimización de software
- Cadenas de caracteres (informática)
