stringtranslate.com

Pasantía de cuerdas

En informática, el internamiento de cadenas es un método para almacenar solo una copia de cada valor de cadena distinto , que debe ser inmutable . [1] El internamiento de cadenas hace que algunas tareas de procesamiento de cadenas sean más eficientes en términos de tiempo o espacio, a costa de requerir más tiempo cuando se crea o interna la cadena. Los valores distintos se almacenan en un grupo de internamiento de cadenas .

La copia única de cada cadena se denomina interna y normalmente se busca mediante un método de la clase de cadena, por ejemplo String.intern() [2] en Java . Todas las cadenas constantes de tiempo de compilación en Java se internan automáticamente mediante este método. [3]

El internamiento de cadenas es compatible con algunos lenguajes de programación orientados a objetos modernos , incluidos Java, Python , PHP (desde 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 de 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 que no sean cadenas. Por ejemplo, en Java, cuando se encapsulan valores primitivos en un objeto contenedor , se internan determinados valores (any boolean, any byte, any charde 0 a 127 y any shorto intentre −128 y 127) y se garantiza que dos conversiones de uno de estos valores darán como resultado el mismo objeto. [6]

Historia

Lisp introdujo el concepto de cadenas internas para sus símbolos . Históricamente, la estructura de datos utilizada como grupo de cadenas internas se denominaba oblist (cuando se implementaba como una lista enlazada) u obarray (cuando se implementaba como una matriz).

Los dialectos modernos de Lisp suelen distinguir entre símbolos y cadenas; al internar una cadena dada se devuelve un símbolo existente o se crea uno nuevo, cuyo nombre es esa cadena. Los símbolos suelen tener propiedades adicionales que las cadenas no tienen (como almacenamiento de valores asociados o espacios entre nombres): la distinción también es útil para evitar comparar accidentalmente una cadena internada con una cadena que no necesariamente lo está, lo que podría provocar fallas intermitentes según los patrones de uso.

Motivación

El internado de cadenas acelera las comparaciones de cadenas, que a veces son un cuello de botella en el rendimiento de las 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 el internado, comparar dos cadenas distintas puede implicar examinar cada carácter de ambas. [Nota 1] 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 lleva 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 interna original; esto normalmente se implementa como una prueba de igualdad de puntero, normalmente solo una única instrucción de máquina sin ninguna referencia de memoria.

La internación de cadenas también reduce el uso de memoria si hay muchas instancias del mismo valor de cadena; por ejemplo, se lee desde una red o desde un almacenamiento . Dichas cadenas pueden incluir números mágicos o información de protocolo de red . Por ejemplo, los analizadores XML pueden internar nombres de etiquetas y atributos para ahorrar memoria. La transferencia de objetos en red a través de flujos de objetos de serialización RMI de Java puede transferir cadenas que se internan de manera más eficiente, ya que el identificador del objeto String se utiliza en lugar de objetos duplicados durante la serialización. [7]

Asuntos

Multiprocesamiento

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 subprocesos múltiples . En muchos sistemas, se requiere que las cadenas internadas sean globales en todos los subprocesos dentro de un espacio de direcciones (o en cualquier contexto que pueda compartir punteros), por lo que el grupo de internaciones 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 internaciones debe verificarse y modificarse si es necesario), y el bloqueo con doble verificación se puede usar en plataformas donde esta es una optimización segura, la necesidad de exclusión mutua al modificar el grupo de internaciones puede ser costosa. [8]

La contención también se puede reducir dividiendo el espacio de cadenas en múltiples grupos, que se pueden sincronizar independientemente unos de otros.

Recuperación de cadenas internas no utilizadas

Muchas implementaciones de cadenas internadas no intentan recuperar (manualmente o de otra manera) cadenas que ya no se usan. Para aplicaciones donde la cantidad de cadenas internadas es pequeña o fija, o que tienen una vida útil corta, la pérdida de recursos del sistema puede ser tolerable. Pero para sistemas de larga ejecución donde se crean grandes cantidades de cadenas internadas en tiempo de ejecución, puede surgir la necesidad de recuperar cadenas internadas no utilizadas. Esta tarea puede ser manejada por un recolector de basura , aunque para que esto funcione correctamente, las referencias débiles a cadenas internadas deben almacenarse en el grupo de cadenas internadas.

Véase también

Notas

  1. ^ La comparación de cadenas puede detenerse en el primer carácter que no coincide. Para lograr una igualdad estricta, las longitudes de las cadenas también se pueden comparar antes de recorrer la cadena, pero para encontrar la longitud de las cadenas terminadas en cero es necesario recorrer la cadena.

Referencias

  1. ^ "Método String.Intern (String)". Microsoft Developer Network . Consultado el 25 de marzo de 2017 .
  2. ^ String.intern()
  3. ^ "Capítulo 15. Expresiones". docs.oracle.com . Consultado el 30 de enero de 2019 .
  4. ^ "wiki de lua-users: objetos inmutables". lua-users.org . Consultado el 30 de enero de 2019 .
  5. ^ rpetrusha. «Clase String (sistema)». docs.microsoft.com . Consultado el 30 de enero de 2019 .
  6. ^ "Capítulo 5. Conversiones y promociones". docs.oracle.com . Consultado el 30 de enero de 2019 .
  7. ^ "Especificación de serialización de objetos Java: 1 - Arquitectura del sistema". docs.oracle.com . Consultado el 30 de enero de 2019 .
  8. ^ "String.intern en Java 6, 7 y 8: acceso multiproceso". java-performance.info . 3 de septiembre de 2013 . Consultado el 30 de enero de 2019 .

Enlaces externos