¿El rendimiento de C# List<T>.ToArray es malo?

¿El rendimiento de C# List<T>.ToArray es malo?

No, eso no es verdad. El rendimiento es bueno ya que todo lo que hace es copiar en memoria todos los elementos (*) para formar una nueva matriz.

Por supuesto, depende de lo que defina como rendimiento "bueno" o "malo".

(*) referencias para tipos de referencia, valores para tipos de valor.

EDITAR

En respuesta a su comentario, usar Reflector es una buena manera de verificar la implementación (ver más abajo). O simplemente piense por un par de minutos cómo lo implementaría y confíe en que los ingenieros de Microsoft no encontrarán una solución peor.

public T[] ToArray()
{
    T[] destinationArray = new T[this._size];
    Array.Copy(this._items, 0, destinationArray, 0, this._size);
    return destinationArray;
}

Por supuesto, el desempeño "bueno" o "malo" solo tiene un significado relativo a alguna alternativa. Si en su caso específico, existe una técnica alternativa para lograr su objetivo que es considerablemente más rápida, entonces puede considerar que el rendimiento es "malo". Si no existe tal alternativa, entonces el rendimiento es "bueno" (o "suficientemente bueno").

EDITAR 2

En respuesta al comentario:"¿No hay reconstrucción de objetos?" :

Sin reconstrucción para los tipos de referencia. Para los tipos de valor, los valores se copian, lo que podría describirse vagamente como reconstrucción.


Razones para llamar a ToArray()

  • Si el valor devuelto no debe modificarse, devolverlo como una matriz aclara un poco el hecho.
  • Si se espera que la persona que llama realice muchos accesos no secuenciales a los datos, puede haber un beneficio de rendimiento para una matriz sobre una Lista<>.
  • Si lo sabe, deberá pasar el valor devuelto a una función de terceros que espera una matriz.
  • Compatibilidad con funciones de llamada que necesitan funcionar con .NET versión 1 o 1.1. Estas versiones no tienen el tipo List<> (ni ningún tipo genérico, para el caso).

Razones para no llamar a ToArray()

  • Si la persona que llama alguna vez necesita agregar o quitar elementos, una Lista<> es absolutamente necesaria.
  • Los beneficios de rendimiento no están necesariamente garantizados, especialmente si la persona que llama accede a los datos de forma secuencial. También existe el paso adicional de convertir de List<> a array, lo que requiere tiempo de procesamiento.
  • La persona que llama siempre puede convertir la lista en una matriz.

tomado de aquí


Sí, es cierto que hace una copia de memoria de todos los elementos. ¿Es un problema de rendimiento? Eso depende de sus requisitos de rendimiento.

Un List contiene una matriz internamente para contener todos los elementos. La matriz crece si la capacidad ya no es suficiente para la lista. Cada vez que eso suceda, la lista copiará todos los elementos en una nueva matriz. Eso sucede todo el tiempo y, para la mayoría de las personas, no representa un problema de rendimiento.

P.ej. una lista con un constructor predeterminado comienza en la capacidad 16, y cuando .Add() el elemento 17, crea una nueva matriz de tamaño 32, copia los 16 valores antiguos y agrega el 17.

La diferencia de tamaño también es la razón por la cual ToArray() devuelve una nueva instancia de matriz en lugar de pasar la referencia privada.