静态列表和垃圾收集器?

时间:2013-09-06 02:10:40

标签: c# entity-framework list garbage-collection

我的应用程序可能会在每个演算中使用大量数据。

我有一个包含很多属性的“A类”。我有大约10k这个类的对象。

  • 所以我的想法是只从数据库中加载一次,然后用它们来搜索。

所以我创建了一个List:

public static List<ClassA>

在我的申请表中。

经过一些测试后,它实际上比每次从数据库中加载数据都要快。

但我认为这不是一个好方法吗? 垃圾收集器怎么样?它会被这个巨大的数据列表所扰乱吗?

  • 我的第二个想法是将我的Class1拆分为不同的类,以便从DB获得较小的请求。我的代码肯定更干净。但现在真的很慢。

我在List方法中看到的唯一一个大问题是我的数据的持久性:我必须修改我的List中的元素(因此在列表中搜索它们)并且还通过EntityFramework保留它们而不是从EF获取它们,修改它们然后通过EF保持它们。

可以肯定的是,避免使用该列表似乎“更好”,但如果我不使用它,那么表现会非常糟糕。

  • 我使用了带有List的探查器,并且花了很多时间来创建列表(每次我搜索它返回一个较小的列表时:例如,取所有属性“Name”等于“blabla”的对象“)

2 个答案:

答案 0 :(得分:1)

  

可以肯定的是,避免使用该列表似乎“更好”,但如果我不使用它,那么表现会非常糟糕。

这是一个非常常见的权衡:您需要为CPU周期和网络带宽支付内存。如果你认为列表永远保留在内存中是一件坏事(作为静态列表肯定会,直到你明确清除它),你可以创建一个“缓存”对象,将列表存储在其中,并保留它仅用于只要它是需要的。完成列表后,删除“缓存”对象,列表将被垃圾收集。

答案 1 :(得分:0)

哇...好的,如果没有对整个申请的明确解释,我会在这里看到一些危险信号。

首先......我主要关注的是你说你已经完成了基准测试,并且已经证明将整个数据库加载到你的应用程序中要比为每个数据库调用的每个对象进行特殊补充更快。

我需要知道你是如何进行基准测试的,以了解你的假设是否正确。

原因如下。

在EF上,查询的主要成本是数据库的延迟,结果集与对象的绑定以及查询的编译。

在静态列表中,主要成本是迭代一个巨大的数据集,以找到正确的项目,线程化错误,而不仅仅是LOH中的一个对象,这会导致内存碎片化。

对于少量对象,将对象绑定到datareader的成本应该很小,但(一次性)编译成本很高。假设一个调整良好的数据库,查询应该是命中索引,这应该会使数据库服务器上的I / O成本变小。

虽然针对大型静态列表的类似查询将在很大程度上得到优化(除非您编写某种索引代码,例如某种关系数据结构)。

最后没有看到你如何构建你的代码,很难理解你如何能够更快地将整个数据库加载到你的应用程序中来加快速度。

您能否展示一些代码清单,说明您实际使用EF的方式,涉及的类,您正在运行的.net框架版本等等。