c# Best type/collection/list/dataset 处理超大数据(csv/tab 文件)

c# Best type/collection/list/dataset to handle super large data (csv/tab files)

我正在构建一个处理非常大的 csv 文件的 WPF (MVVM) 应用程序。我们说的是 1GB 到 10GB。

我打开文件并用 File.ReadLines 将其解析为以下列表 class:

public class FileLine
{
    public DateTime Time { get; set; } 
    public string Message { get; set; } //Usually around 256 characters
    public string Info1 { get; set; } //Exact 56 characters
    public string Info2 { get; set; } //Exact 4 characters
    //and so on
}

...然后我会进行各种数据操作、查询、图表...只要您能想到...一切都使用 Linq。

我们正在测试一个 1.8GB 的​​文件,当它打开时,该过程占用大约 2GB 的内存。

最终,当我的客户需要打开他的 10GB 文件时,这是不可能的,因为它将占用 12GB+ 的内存。 这种工作最好的是什么type/collection/list/dataset?

当我不得不做这样的事情之前,我通过一个包含字典列表的容器对象来处理它。当时我认为限制 would/should 是 2^32 个元素,但是在获得 2^32 个元素之前抛出了超出集合的异常并且仍然​​有很多 GB 的 ram。假设你想要一个字典,这样的东西应该可以工作,直到你真的用尽所有的物理和虚拟内存......一个可能的解决方案如下......我记得几年前我工作时服务器实际上有 512Gb ram,我敢肯定他们现在有更多的...无论如何这是一个单独的故事。

   public class MyHugeDictionary  
   {  
        List<Dictionary<typea, typeb> allDict= null;  
        Dictionary<typea, typeb> currDictionary ;  

        MyHugeDictiionary()  
        {  
            allDict = new List<Dictionary<typea, typeb>();  
            currDictionary = new Dictionary<typea, typeb);  
            allDict.Add(currDictionary);  
        }  

        public bool ItemExists( typea, typeb)  
        {  
            foreach( KeyValue<Dictionary<typea, typeb> kv in allDict)  
            {  
                if( kv.ContainsKey(typea) )  
                {  
                    return true;  
                }  
            }  
            return false;  
        }  

        public Add( typea a, typeb b)  
        {  
            try  
            {  
                if( !ItemExist( tyepa, typeb) )  // find if items is in any other dictionary first  
                {  
                    currDictionary.Add( a, b) ;  
                }  
                else  { // handle dups... ; }  
            }  
            catch( CollectionSizeError x)   // look-up for actual exception
            {  
                currDictionary = CreateDictiionary();  
                allDict.Add( currDictionary ) ;  
                currDictionary.Add( a,b);  
            }  
            catch( OutOfMemory y)     // look-up for actual exception
            {  
                // oops game over for real now :(  
            }  
         }  
    }  

经过一番讨论,最好的办法是读取文件,处理它,然后处理掉所有其他的东西,只坚持结果。

另一种可能性是使用数据库,但它会增加太多的复杂性,尽管这是可能的。

看到这个:

https://github.com/aumcode/nfx/tree/master/Source/NFX/ApplicationModel/Pile https://www.infoq.com/articles/Big-Memory-Part-3

您可以存储任何您想要的 - 没有停顿。 大集合的问题是: 一种。它们并不是真正设计用于容纳很多条目(即字典永远不会缩小到零大小) b.当你有太多对象时你得到 GC stalls/pauses

查看上面的链接 - 我们所做的是 "hiding" 来自 GC 的数据,如文章中所述。这样,您可以使用 LocalCache class 作为字典来存储数百万个对象。

对于网络中的大内存应用程序 - 请记住在您的应用程序配置文件中启用 64 位并将 GC 设置为服务器模式