目前,我正在开发一个项目,我需要将数据的GB数据传输到客户端计算机上来执行某项任务,并且任务需要整个数据,因为它会对数据进行一些分析,并有助于决策制定过程。
所以问题是,在不影响客户端计算机和应用程序性能的情况下,将大量数据管理到内存中的最佳实践和合适方法是什么。
注意:在加载应用程序时,我们可以花时间将数据从数据库传输到客户机,这在我们的案例中是完全可以接受的。但是一旦数据在启动时加载到应用程序中,性能就非常重要。
答案 0 :(得分:14)
如果没有问题陈述,这有点难以回答,即您目前面临的问题,但以下只是一些想法,基于我们在类似场景中的一些近期经验。然而,要改变这种类型的模型需要付出很多努力 - 所以它还取决于您可以投入多少资金来“修复”它,而且我不能保证“您的问题”与“我们的问题”相同问题“,如果你明白我的意思。所以,如果以下方法对您不起作用,请不要交叉!
将大量数据加载到内存中总会产生一些影响,但是,我想我知道你在做什么......
当天真地加载那么多数据时,你将拥有许多(数百万?)个对象和相似或更多数量的引用。你显然想要使用x64,所以引用会加起来 - 但就性能来说,最大的问题是垃圾收集。你有很多永远无法收集的对象,但GC会知道你正在使用大量的内存,并且会定期尝试 。这是我查看in more detail here的内容,但下图显示了影响 - 特别是那些“峰值”都是GC杀戮性能:
对于这种情况(加载了大量数据,从未发布过),我们使用结构切换到,即将数据加载到:
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
,您无法存储。但是,你可以做的是存储索引(进入数组)。例如:
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个字节)补充说明:
string.Intern
,这将是坏的),以确保你只有一个实例的每个重复值,而不是800,000字符串与相同的内容fixed
数组;这需要unsafe
代码,但避免使用其他无数的对象和引用作为一个额外的脚注,有了这么多的数据,你应该非常认真地考虑你的序列化协议,即你如何通过网络发送数据。我强烈建议远离XmlSerializer
,DataContractSerializer
或BinaryFormatter
等内容。如果您想了解这个主题,请告诉我。