gpt4 book ai didi

c# - 大数据的内存表示

转载 作者:太空狗 更新时间:2023-10-29 20:00:03 25 4
gpt4 key购买 nike

目前,我正在开展一个项目,我需要将数 GB 的数据带到客户端计算机上以执行某些任务,而该任务需要完整的数据,因为它对数据进行了一些分析并有助于决策过程。

所以问题是,在不影响客户端机器和应用程序性能的情况下,将大量数据管理到内存中的最佳实践和合适方法是什么。

注意:在加载应用程序时,我们可以花时间将数据从数据库传输到客户端机器,这在我们的案例中是完全可以接受的。但是一旦数据在启动时加载到应用程序中,性能就非常重要。

最佳答案

如果没有问题陈述,即您目前面临的问题,这有点难以回答,但以下只是一些想法,基于我们最近在类似情况下的一些经验。然而,要改变这种类型的模型需要做很多工作——所以这也取决于你能投入多少来试图“修复”它,我不能保证“你的问题”和“我们的问题”是一样的问题”,如果你明白我的意思。如果以下方法对您不起作用,请不要生气!


将那么多数据加载到内存中总是会产生一些影响,但是,我想我明白你在做什么......

当天真地加载那么多数据时,您将拥有许多(数百万?)对象和类似或更多数量的引用。您显然会想要使用 x64,因此引用会加起来 - 但就性能而言,最大的问题将是垃圾回收。您有很多永远无法收集的对象,但 GC 会知道您正在使用大量内存,并且会定期尝试无论如何 .这是我看过的in more detail here ,但下图显示了影响 - 特别是,那些“尖峰”都是 GC 终止性能:

http://marcgravell.blogspot.co.uk/2011/10/assault-by-gc.html

对于这种情况(大量数据加载,从未释放),我们切换到使用结构,即将数据加载到:

struct Foo {
private readonly int id;
private readonly double value;
public Foo(int id, double value) {
this.id = id;
this.value = value;
}
public int Id {get{return id;}}
public double Value {get{return value;}}
}

并将它们直接存储在数组(不是列表)中:

Foo[] foos = ...

这样做的意义在于,因为其中一些结构非常大,我们不希望它们在堆栈上多次复制自己,但是使用数组你可以这样做:

private void SomeMethod(ref Foo foo) {
if(foo.Value == ...) {blah blah blah}
}
// call ^^^
int index = 17;
SomeMethod(ref foos[index]);

请注意,我们直接传递了对象——它从未被复制过; foo.Value 实际上是直接查看数组内部。当您需要对象之间的关系时,棘手的部分就开始了。您不能在此处存储引用,因为它是一个结构,而且您不能存储。但是,您可以 做的是存储索引(到数组中)。例如:

struct Customer {
... more not shown
public int FooIndex { get { return fooIndex; } }
}

不如 customer.Foo 方便,但下面的工作很好:

Foo foo = foos[customer.FooIndex];
// or, when passing to a method, SomeMethod(ref foos[customer.FooIndex]);

要点:

  • 我们现在将一半的大小用于“引用”(int 是 4 个字节;x64 上的引用是 8 个字节)
  • 我们的内存中没有几百万个对象头
  • 我们没有大型对象图供 GC 查看;只有少数数组 GC 可以难以置信地快速查看
  • 但使​​用起来有点不方便,加载时需要一些初始化处理

补充说明:

  • 字符串是 killer ;如果你有数百万个字符串,那就有问题了;至少,如果您有重复的字符串,请确保您进行了一些自定义实习(不是 string.Intern,那会很糟糕)以确保每个重复值只有一个实例,而不是超过 800,000 个内容相同的字符串
  • 如果您有有限长度的重复数据,而不是子列表/数组,您可以考虑使用固定数组;这需要不安全代码,但避免了另外无数的对象和引用

作为附加脚注,对于如此大量的数据,您应该非常认真地考虑您的序列化协议(protocol),即您如何通过网络发送数据。我强烈建议远离诸如 XmlSerializerDataContractSerializerBinaryFormatter 之类的东西。如果您需要有关此主题的指示,请告诉我。

关于c# - 大数据的内存表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12401042/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com