sábado, 6 de julio de 2013

Tipos por Valor vs. Tipos por Referencia

Tabla de Contenido

0. Introducción
1. Tipos por Valor y Tipos por Referencia
2. Tipo por Valor
2.1 struct
3. Tipos por Referencia
4. Contraste
4.1 Rendimiento
4.2 Espacio en memoria
5. Conclusiones
6. Palabras clave
7. Literatura & Enlaces

0. Introducción

En esta nueva oportunidad exploraremos y entenderemos las categorías especializadas para el tratamiento de valores y referencias a instancias de objetos. Para ello, será necesario reconocer las categorías de tipo por valor y tipo por referencia. Inclusive, se ejemplificará las situaciones donde resulta útil comprender estos conceptos adecuadamente para el diseño e implementación de un método. En las secciones prácticas será necesario recurrir a la construcción struct para explicitar la diferencia entre tipos por valor y tipos por referencia. Al final, se resaltarán algunos  de los aspectos de rendimiento y mínimo espacio consumido en memoria por parte de estas categorías especializadas de valores y referencias a instancias de objetos.

1. Tipos por Valor y Tipos por Referencia
Clasificación manejo de tipos de datos
Figura 1. Clasificación manejo de tipos de datos.

El lenguaje de programación C# cuenta con varias categorías para los tipos de datos:
  • Tipos por valor
  • Tipos por referencia
  • Parámetros genéricos
  • Punteros
[Nota: estos dos últimos serán tema de estudio en artículos especializados.]

2. Tipos por Valor

Los tipos primitivos (también conocidos en otros lenguajes como primitivos, integrales, básicos) están integrados por defecto en el lenguaje C#: numéricos (shortintlongfloatdouble, etc.), el tipo char  y el tipo bool. Otros tipos de datos por valor especiales son los personalizados (struct) y los tipos enum.

De acuerdo a la definición en [2]: una variable o constante de tipos por valor almacena un valores como 5.0 (double), 'h' (char), 7 (int).

2.1 struct

Un struct es un tipo por valor que permite la encapsulación de grupos variables relacionadas, por ejemplo las coordenadas de un punto geométrico. Así como es posible crear tipos de datos personalizados (lectura recomendad en [3]) como clases, los tipos por valor permiten crear construcciones para modelar un objeto del mundo (e.g., Persona, Carro, Triángulo). Estamos hablando de las construcciones struct. A continuación un ejemplo de demostración de su uso:

Archivo C# Punto.cs [Enlace alternativo]:

La Figura 2 representa de forma gráfica una instancia del tipo por valor Punto en memoria:
Estructura Punto
Figura 2. Representación gráfica de una instancia tipo por valor en memoria.
Ahora para demostrar una de las propiedades interesantes de los tipos por valor utilizamos el siguiente código de prueba:

Archivo C# PruebaPunto.cs [Enlace alternativo]:

La propiedad en cuestión consiste en que los tipos por valor a la hora de asignarse, como en el caso de Punto punto2 = punto1; (línea 6), crean una copia. (Más adelante se explicitará que en los tipos por referencia no ocurre lo mismo, lo que resulta en una de las diferencias fundamentales entre estas categorías de los valores de tipos de datos.)

En la Figura 3 se diagrama el proceso de ejecución de la línea 11:
Estructura Punto - La asignación copia una intancia de tipo por valor
Figura 3. La asignación copia una instancia de tipo por valor.

3. Tipos por Referencia

En [4] se encuentra esta interesante definición: «los tipos creados por referencia almacenan la dirección de memoria en la que se encuentra un dato determinado de manera que se usa esa dirección de memoria para acceder de forma indirecta al dato». Esta propiedad, producto de la evolución de los lenguajes de programación de alto nivel, facilita al programador centrarse en los asuntos de su interés; principalmente, el de resolver el problema de negocio e ignorar asuntos técnicos complejos de manipulación de recursos: asignación de espacio en memoria.

Los tipos por referencia son muchos más complejos que los tipos por valor debido a que están compuestos por dos partes:
  • un objeto que reside efectivamente en la memoria, y
  • una referencia a ese objeto.
Si reescribimos al objeto Punto utilizando la construcción de clase, se tiene:

Archivo C# Punto.cs [Enlace alternativo]:

¿Qué ocurre si se crea una instancia de esta clase (Punto)? ¿Cuál es su representación pictórica en memoria? En la Figura 4 encontramos la respuesta.
Instancia de la clase Punto
Figura 4. Instancia de tipo por referencia en memoria.
Cuando se asigna una variable de tipo por referencia a otra, se está copiando la referencia al objeto y no los datos del objeto (esto es lo que ocurre con los tipos por valor: crean una copia de los datos). En el siguiente fragmento de código, la clase cliente PuntoPrueba se puede apreciar mejor el concepto anterior:

Archivo C# PuntoPrueba.cs [Enlace alternativo]:

Una vez se ejecuta este código, la Figura 5 nos muestra la representación pictórica de las referencias punto1 y punto2 en memoria.
Asignación de una instancia Punto
Figura 5. La sentencia de asignación copia la referencia.

4. Contraste

Ahora un breve contraste de estas dos clasificaciones de los tipos en C#.

4.1 Rendimiento

Los tipos de datos por valor pueden [5] residir en la memoria stack [6]; esta característica permite que la recuperación y almacenamiento de valores desde/hacia la variable sea mucho más rápido que si estuviera almacenado en la memoria heap [6].

4.2 Espacio en memoria

Debido a la complejidad que representa el uso de referencias, como se describió en el tema anterior, además de las manipulaciones y chequeos adicionales, el espacio en memoria requerido para almacenar los datos asociados a un objeto ocupa mucho más que un valor por referencia.

5. Conclusiones

Se ha visto como los tipos de datos por valor son mucho más simples que los por referencia. Además, los tipos por referencia requieren de manipulaciones más complejas y son almacenados en la memoria heap. Se introdujo además el concepto de struct, el cual permite crear estructuras personalizadas de tipos primitivos. Al final, se realizó un breve recorrido que muestra asuntos de rendimiento y espacio en memoria de estos dos tipos de datos.

6. Palabras Clave

  • Heap
  • struct
  • Stack
  • Tipo por referencia
  • Tipo por valor

7. Literatura & Enlaces

[1] Structs - http://msdn.microsoft.com/en-us/library/saxz13w4.aspx
[2] C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.[3] Tipos Básicos en C# - Parte 2 - http://ortizol.blogspot.com/2013/07/tipos-basicos-en-c-parte-2.html
[4] Tipos de datospor valor y tipos por referencia - http://www.desarrolloweb.com/articulos/1389.php
[5] The Truth About Value Types - http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx
[6] Six important .NET concepts: Stack, heap, value types, reference types, boxing, and unboxing - http://stackoverflow.com/questions/3942721/structs-versus-classes


V

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.