Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取列表数组并保留引用?_C#_Performance_Reflection_Reference - Fatal编程技术网

C# 获取列表数组并保留引用?

C# 获取列表数组并保留引用?,c#,performance,reflection,reference,C#,Performance,Reflection,Reference,出于性能原因,我想直接在C中获取列表数组# 我的代码在这里: private UIVertex[] GetArray(List<UIVertex> verts) { var aryF = typeof(List<UIVertex>).GetField("_items", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Insta

出于性能原因,我想直接在C中获取列表数组#

我的代码在这里:

private UIVertex[] GetArray(List<UIVertex> verts)
    {
        var aryF = typeof(List<UIVertex>).GetField("_items", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        return aryF.GetValue(verts) as UIVertex[];
    }

private void SetSize(List<UIVertex> list, int size)
{
        sizeF = typeof(List<UIVertex>).GetField("_size", 
        System.Reflection.BindingFlags.NonPublic | 
        System.Reflection.BindingFlags.Instance);
}

static List<UIVertex> verts
static UIVertex[] ary;
//...
ary = GetArray(verts);
以下是修改后的内容:

static List<T> Orgin = new List<T>(128);
static T[] StaticAry;
void DO() // *it call a lot of times.*
{
    bool LastOringCapacity = Orgin.Capacity;
    GetListByAPI(Orgin);// here is API , So it must insert List<T>.

    bool arrayRefChanged = Orgin.Capacity > LastOringCapacity ; // I Can know it. and get array again. 

    int Size = Orgin.Count() * 5; // size is unchanged in here.
    SetSize(Oring, Size);//here set array legth of list by refection
    StaticAry = GetArray(Orgin);//here I get array of list by reflection
    
    for(int i = 0 ; i < size; i++)
    {
        T t = StaticAry[i];//just use it , avoid to use List.Add api. 
        //....
    }
}
静态列表来源=新列表(128);
静态T[]静态;
void DO()/*它调用了很多次*
{
bool LastOringCapacity=原容量;
GetListByAPI(Orgin);//这里是API,所以它必须插入列表。
bool arrayRefChanged=Orgin.Capacity>LastOringCapacity;//我可以知道它。然后再次获取数组。
int Size=Orgin.Count()*5;//此处的大小不变。
SetSize(Oring,Size);//此处通过引用设置列表的数组长度
StaticAry=GetArray(Orgin);//这里我通过反射得到列表的数组
对于(int i=0;i
这个静态组织是重用的,所以Oring。容量可能不会改变。所以Orgin的数组也不需要调整大小。我想得到数组地址。直接使用它。 但是现在。我需要在每个DO()中使用反射来获取数组

最复杂的地方是
List.Capacity
Array.Length
List.Count()
是三个不同的值。

ListCount
发生更改时(实际上是
容量
),这是因为列表的内部数组已调整大小

调整较大数组的大小需要分配一个新数组并复制其内容,同时忘记旧的内存空间

理论上,收缩不是问题,只需要“切割”阵列

但是由于内存单元的组织,如果不使用具有完整可用空间的全新连续块,就不可能确保内存的增长

:

此方法分配具有指定大小的新数组,将元素从旧数组复制到新数组,然后用新数组替换旧数组。数组必须是一维数组

因此,您无法避免:每次调整数组大小时,您都需要再次获取它。

因此,除非您一次做一次这样的事情,并且确保阵列的容量不会改变,否则我不推荐您使用的技术,因为很难确保您始终拥有正确的阵列,而不是放弃的引用

因此,您应该使用已经存在的方法

但是事实上,如果可以的话,因为你想要速度,你应该使用一个而不是
列表

如您所见,当
容量
计数
超过
容量
时,
列表
在以下方面发生变化:

下面是
Add
方法:

public void Add(T item) {
  if (_size == _items.Length) EnsureCapacity(_size + 1);
  _items[_size++] = item;
  _version++;
}
Array.Resize()
执行相同的操作:

if (larray.Length != newSize) {
  T[] newArray = new T[newSize];
    Array.Copy(larray, 0, newArray, 0,  larray.Length > newSize? newSize : larray.Length);
    array = newArray;
}

我认为,这本可以针对缩减规模的情况进行优化,但可能有一些与CLR或GC相关的原因。

有一些方法可以加快反射-是的。但是,像这样使用反射将数组从列表中取出是不明智的(例如,数组的条目可能比您预期的多)。如果您遇到性能问题,请向我们展示更多上下文,我们可以提供替代方案?当更改时,\ u项将复制到新数组并替换。你希望ary怎么处理?听起来像个X-Y问题。您能详细说明一下
某些性能原因吗
?首先为什么要使用
列表
?通过从ArrayPool租赁和复制等方式自行管理。对你的LOB更好,你可以控制扩张。并且始终可以访问阵列或span(如果需要,请锁定)@Martheen我将检查容量是否已更改,并重新获取阵列,但在我的情况下几乎没有更改@zaitsman,因为当我使用
List.Add
List.Get
时,它是触发器
String.memcpy()
,它太慢了,我可以确定我的数组计数,所以我不需要List,我使用List只是因为我使用的API接口需要它。谢谢你的解释,非常清晰和详细,我想我会尝试使用ToArray()与更快的refelction相比:)ToArray()在调用方法时提供了一个数组副本,就像快照一样。。。如果可以将变量的类型从列表更改为数组,那么这是优化处理速度的最佳、稳定且干净的选项。
public void Add(T item) {
  if (_size == _items.Length) EnsureCapacity(_size + 1);
  _items[_size++] = item;
  _version++;
}
if (larray.Length != newSize) {
  T[] newArray = new T[newSize];
    Array.Copy(larray, 0, newArray, 0,  larray.Length > newSize? newSize : larray.Length);
    array = newArray;
}