我有两个包含两个只读结构的大数组:A和B。我需要枚举它们,但是我需要以最优化的方式进行操作。
readonly struct A {
long a;
long b;
long c;
long d;
long e;
long g;
}
readonly struct B {
byte a;
ushort b;
}
如您所见,类型A非常大struct
,可以一遍又一遍地复制它,因此我制作了自定义枚举器,该枚举器通过引用(struct
)返回了此ref return
。类型B不需要它,因为它的大小只有4个字节。现在,我只需要使用单个foreach循环就可以使两个枚举器同时移动,因为直接调用Enumerator的方法(即MoveNext,Current)看起来并不像本地调用那样。
我的问题是,当我尝试将两个结构保存在一个聚合中时,struct A
被复制,而我的性能损失也消失了。
public readonly struct Aggregate
{
public readonly A ItemA;
public readonly B ItemB;
public Aggregate(A itemA, in B itemB)
{
ItemA = itemA;
ItemB = itemB;
}
}
此聚合的总大小为56个字节。当我将结构分配给另一个结构的属性时,C#复制该结构听起来很合逻辑。但是我该怎么办?我只需要引用数组的元素。我认为,使用不安全的代码获取指针不是正确的方法,因为GC可以移动我的数组(如果数组足够小并且不在LOH区域中)。
那么您可以向我提出什么解决方案?
答案 0 :(得分:1)
我不知道我是否理解您的问题正确,但是您在谈论数组。
假设:两者都是大小相同的数组
你可以做到
for (int i = 0; i < length; i++)
{
ref var aItem = ref arrayA[i];
ref var bItem = ref arrayB[i];
//do your stuff
}
答案 1 :(得分:0)
您可以显式使用枚举器,而无需foreach循环:
var aEnumerator = listA.GetEnumerator();
var bEnumerator = listB.GetEnumerator();
while (aEnumerator.MoveNext() && bEnumerator.MoveNext()) {
var aItem = aEnumerator.Current;
var bItem = bEnumerator.Current;
//TODO: do some work
}