0

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

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

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

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

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

4

4 回答 4

1

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

鉴于以下要求和约束:

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

第一个和最后一个要求让我认为数组仍然是您情况下的最佳解决方案(而 List 在频繁调整大小的情况下很有趣(由于它的容量属性))。

现在,要“调整”数组的大小,您有两种可能性:

  1. Array.Resize()如果您需要保留前一个数组中的数据。
  2. 如果您不需要以前的数据,则创建一个新数组
于 2013-07-24T23:30:17.987 回答
0

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

您可以简单地使用List<object>和在需要数组的地方使用它的ToArray(..)调用。

编辑

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

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

编辑

考虑到您正在谈论GPU交互,因此您有非常大的带有 3D 数据的顶点数组,如果您的情况可能,我建议使用由Array提供的简单C#代码并使用带有 * 指针的不安全代码(我m 不知道GPU端调用方法的签名)。

所以不会有任何动态分配,必须由您的代码根据要求处理。

于 2013-07-24T21:53:27.183 回答
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);
        }
    }
}
于 2013-07-24T21:59:04.250 回答
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 不太熟悉,所以我不能给你示例代码,但它会非常相似。

于 2013-07-24T22:32:13.530 回答