我需要一个暴露数组的动态集合类型

时间:2013-07-24 21:52:07

标签: c#

我需要一个集合类型,它将按照添加顺序将所有内容存储在数组中,它需要动态增加大小,并且需要将数组公开为公共字段/属性以供读取。

我已经确定c#List.ToArray()对我来说太贵了。

是否有符合我要求的收藏类型?如果没有,你能引荐我参加一个允许我这样做的自定义课吗?

编辑:为了添加更多信息,我为人们提供了基准测试.ToArray(),其目的是将结构数组发送到图形卡,以便它可以渲染顶点。所以如果你想知道为什么我需要数组,那就是原因。

Edit2:缓冲区停留在CPU上,并且每帧只发送到GPU,因为它经常变化,但它的大小不会经常变化。

4 个答案:

答案 0 :(得分:1)

您对帖子的第二次编辑提供了解决方案。

鉴于以下要求和限制:

  • 该集合必须提供对(底层)数组的快速访问,因为它用于动态使用GPU(每帧访问)
  • 它的内容经常被修改,但不是它的大小。
  • 有时会调整大小(不经常)

第一个和最后一个要求使我认为数组仍然是您的最佳解决方案(而在经常调整大小的情况下,List很有意思(由于其容量属性))。

现在,为了“调整”你的数组,你有两种可能性:

  1. Array.Resize()如果您需要保留上一个数组中的数据。
  2. 如果您不需要以前的数据,则创建一个新数组

答案 1 :(得分:0)

  

我需要一个集合类型,它将所有内容存储在数组中   订单它被添加,它需要动态增加大小,它   需要将数组公开为公共属性以供阅读。

您只需使用List<object>并在需要数组的地方使用ToArray(..)电话。

编辑

如果由于某种原因ToArray(..)对您不利(“太贵”),您可以使用同一个对象通过索引访问它。如果这是您的要求。

如果这不是您所要求的,请澄清。

编辑

考虑到你在谈论 GPU 交互,所以你有大量的顶点数据与3D数据,我建议使用{{1}提供的简单Array并使用带有*指针的不安全代码,如果可能的话, (我不知道 GPU 侧的调用方法的签名)。< / p>

因此,没有任何动态分配,必须由您的代码根据请求处理。

答案 2 :(得分:0)

public class MyList<T> : List<T>
{
    private FieldInfo _finfo = 
         typeof(List<T>)
         .GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance);
    public T[] Items
    {
        get
        { 
            return (T[])_finfo.GetValue(this);
        }
    }
}

答案 3 :(得分:0)

单个副本不会花费太多,除非数组很大,如大对象堆大。唯一不适用的情况是,如果您正在尝试为Windows Phone或Xbox 360编写游戏,垃圾收集会阻塞并且需要很长时间。

在这种情况下,我建议创建一个比您需要的大得多的静态数组,并将其传递给具有适当长度的GPU。

如果您向我们提供了更多详细信息,我可以就如何避免额外开销提出更多建议。如果您使用unsafe没问题,我建议您查看内存映射缓冲区并直接使用它给出的指针。但是,如果不重新分配缓冲区,您将无法调整其大小,因此请确保它足够大以便开始。

示例,使用OpenGL:

unsafe
{
    glBindBuffer(GL_ARRAY_BUFFER, myBuffer);
    float* bufferPtr = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);

    // Update the buffer here, reading and writing to the pointer.

    glUnmapBuffer(GL_ARRAY_BUFFER);
}

我对Direct3D并不熟悉,所以我不能给你示例代码,但它会非常相似。