C # equivalente del vector C ++, con memoria contigua?

4 minutos de lectura

avatar de usuario
edgarmtze

¿Cuál es el equivalente C# del vector C++?

Estoy buscando esta característica:

Tener una matriz dinámica de memoria almacenada de forma contigua que no tenga una penalización de rendimiento para el acceso frente a las matrices estándar.

estaba buscando y dicen .NET equivalent to the vector in C++ is the ArrayListasi que:

¿ArrayList tiene esa función de memoria contigua?

  • ¿No está el CLR lo suficientemente cerca del metal como para especificar (o incluso esperar consistentemente) cómo se asigna una estructura en la memoria?

    – Aphex

    4 de agosto de 2011 a las 14:31

Podrías usar un List<T> y cuando T es un tipo de valor que se asignará en la memoria contigua que no sería el caso si T es un tipo de referencia.

Ejemplo:

List<int> integers = new List<int>();
integers.Add(1);
integers.Add(4);
integers.Add(7);

int someElement = integers[1];

  • No estoy 100% familiarizado con CLR, pero tiene sentido que incluso si T es un tipo de referencia, aún tendrá memoria contigua. Es básicamente una serie de punteros…

    – josafatv

    10 de agosto de 2013 a las 10:01


  • “que no sería el caso si T es un tipo de referencia” – es tanto el caso como para T[] … el OP solicitó “ninguna penalización de rendimiento para el acceso frente a matrices estándar”, y List<T> proporciona eso. Y si T es un tipo de referencia, que es análogo a T* en C++, por lo que obtiene tanta contigüidad como en C++. Si uno quiere que los objetos mismos sean contiguos, entonces, por supuesto, necesita tipos de valor… en ambos idiomas. La diferencia, por supuesto, es que en C++ cualquier tipo puede usarse como valor o referencia, mientras que en C# es una propiedad del tipo a través de la distinción de clase/estructura.

    –Jim Balter

    28 de julio de 2015 a las 2:36


  • Aprendí algo hoy. Pensé List<T> siempre se implementa como una lista enlazada internamente. Entonces, ¿cómo se expande dinámicamente cuando llamamos Add()? Algo así como VB6 Redim Preserve que solía copiar toda la matriz a una nueva ubicación?

    – punto net

    7 de octubre de 2016 a las 7:42


  • @dotNet, internamente List<T> crea una pequeña matriz T[]. Los elementos internamente se agregan a la matriz. Una vez que se completa el tamaño de la matriz, se crea una nueva matriz del doble del tamaño de la anterior. Los datos se copian en la nueva matriz más grande, la más pequeña se destruye, y así sucesivamente. Un desarrollador puede dar una pista a .NET para crear una matriz interna lo suficientemente grande antes de llenar el List a través del constructor: new List<T>(expected_array_size).

    – Arturo A.

    27 de agosto de 2020 a las 20:51


usar List<T>. Internamente usa arreglos y los arreglos usan memoria contigua.

  • No del todo cierto. Si T es un tipo de referencia, no habrá memoria contigua.

    – Mateo Mosca

    4 de agosto de 2011 a las 14:34

  • @Matteo si miras la fuente, hay private T[] _items; que se utiliza para el almacenamiento de back-end, tipo de referencia o no.

    – Bala R.

    4 de agosto de 2011 a las 14:37


  • Bueno, eso lo sé. Pero dime. Tienes una Lista. Las referencias a las instancias de SomeClass se almacenarán en la memoria contigua, pero no las instancias en sí. Como tipos de referencia, estarán en el montón y seguramente sabrás cómo funciona el montón.

    – Mateo Mosca

    4 de agosto de 2011 a las 14:39

  • @MatteoMosca almacenar las referencias de forma contigua al menos elimina un nivel de direccionamiento indirecto. Mejor que nada, supongo.

    – Tim Séguine

    18/11/2014 a las 21:34


  • @MatteoMosca El OP solicitó “ninguna penalización de rendimiento para el acceso frente a matrices estándar”. Eso es cierto para List independientemente de lo que sea T, por lo que todos sus comentarios en esta página están fuera de lugar.

    –Jim Balter

    28 de julio de 2015 a las 2:30

En primer lugar, manténgase alejado de Arraylist o Hashtable. Esas clases deben considerarse en desuso, a favor de los genéricos. Todavía están en el idioma con fines heredados.

Ahora lo que buscas es el List<T> clase. Tenga en cuenta que si T es un tipo de valor, tendrá memoria contigua, pero no si T es un tipo de referencia, por razones obvias.

C# tiene muchos tipos de referencia. Incluso si un contenedor almacena el referencias contiguamente, los objetos mismos pueden estar dispersos a través del montón

Parece que CLR/C# pronto obtendrá una mejor compatibilidad con Vector.

http://blogs.msdn.com/b/dotnet/archive/2014/04/07/the-jit-finally-proposed-jit-and-simd-are-getting-married.aspx

¿Ha sido útil esta solución?