【发布时间】:2019-05-19 06:30:13
【问题描述】:
我有两个包含两个只读结构的大数组: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 以一遍又一遍地复制它,所以我创建了我的自定义枚举器,它通过引用 (ref return) 返回此 struct。 B 型不需要它,因为它的大小只有 4 个字节。现在我需要让两个枚举器同时移动,只使用一个 foreach 循环,因为直接调用枚举器的方法(即 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 区域中)。
那么您可以向我提出什么解决方案?
【问题讨论】:
-
我看不到不使用 IEnumerable 的原因
-
@Steve,对我来说一遍又一遍地复制结构并不是很好。我在问题中写了它
-
你没有告诉我们你在哪里复制它们。如果您只需要枚举两个数组,那么您什么都不会复制。如果你想通过 ref addr 引用,你应该使用 class 而不是 struct
-
使
A成为一个类,而不是一个结构。这就是您在使用它的任何地方获得引用语义的方式,这似乎是您想要的。 -
@Servy,那么我的程序会受到影响,因为 GC 会关心堆中的所有对象