3 回答
TA贡献1995条经验 获得超2个赞
如果你需要一个List<int>
,你不能这样做。AList<int>
总是直接包含它的数据,所以当你有两个(比如说)100 个元素的数组和一个通过连接这两个元素创建的列表时,你已经有了 400 个独立元素。你无法改变这一点。
您正在寻找的是一种不创建数据的独立副本的方法。如果您只是在搜索它(就像评论中的声音一样),您可以使用使用IEnumerable<int>
LINQ 创建的:
IEnumerable<int> concat = a.Concat(b);
如果您需要类似 anIReadOnlyList<T>
甚至 an 的东西IList<T>
,您可以自己实现这些接口以在多个数组上创建适配器 - 但您可能需要自己编写。如果你能坚持IEnumerable<T>
使用 LINQ,使用 LINQ 会简单很多。
TA贡献1827条经验 获得超8个赞
我可以建议您进行一些优化:
IEnumerable<int>在不调用 ToArray() 方法的情况下初始化 a 和 b
int size = 1000 * 1024 * 1024 / 4;
IEnumerable<int> a = Enumerable.Range(0, size);
IEnumerable<int> b = Enumerable.Range(0, size);
用已知容量初始化 concat
List<int> concat = new List<int>(size);
结果我得到以下输出:
Initial memory size: 12 MB
Memory size after lists initialization: 13 MB
Memory size after lists concatenation: 1021 MB
如果您只想串联搜索某些内容,则可以这样做而无需额外分配:
IEnumerable<int> concat = a.Skip(500 * 1024 * 1024 / 4).Concat(b.Skip(500 * 1024 * 1024 / 4));
int search = concat.Count(i => i % 2 == 0);
Console.WriteLine($"Search result: {search}");
TA贡献1895条经验 获得超7个赞
他们是执着的。我只需要连接它们,进行一些搜索,然后处理连接列表
如果您只需要进行一些搜索,为什么首先需要连接?分别搜索两个数组。
您正在搜索的内容可能会桥接两个数组。如果是这种情况,为了让事情变得更容易并且不支付内存价格,只需实现一个模拟操作但实际上不执行它的包装器:
sealed class Concatenated<T>:
IReadOnlyList<T>
{
public static Concatenated<T>
Concatenate<T>(
IReadOnlyList<T> first,
IReadOnlyList<T> second)
=> new ConcatenatedArray<T>(first, second);
private readonly IReadOnlyList<T>
first, second;
private Concatenated(
IReadOnlyList<T> first,
IReadOnlyList<T> second)
{
this.first = first;
this.second = second;
}
public T this[int index]
=> index < first.Length ?
first[index]:
second[index - first.Length];
public int Count => first.Length + second.Length;
public IEnumerator<T> GetEnumerator()
{
foreach (var f in first)
yield return f;
foreach (var s in second)
yield return s;
}
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
}
- 3 回答
- 0 关注
- 95 浏览
添加回答
举报