【问题标题】:c# Best type/collection/list/dataset to handle super large data (csv/tab files)c# 处理超大数据(csv/tab 文件)的最佳类型/集合/列表/数据集
【发布时间】:2016-01-28 23:00:13
【问题描述】:

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

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

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 以上的内存。 这种工作的最佳类型/集合/列表/数据集是什么?

【问题讨论】:

  • 恐怕有人会告诉我使用SQL Server...只是说。
  • 这将花费很长时间.. 使用更强大的东西来存储数据,例如将其存储到 Oracle DB, || Sql Server
  • 你真的需要一次将它全部加载到内存中吗?你在这里的用例是什么?恐怕这个问题目前的范围太广了。
  • Eventually, when my customer needs to open his 10GB file it will be impossible, because it is going to take 12GB+ of Memory. 不,那是just not true。 (尽管尝试将这么多数据加载到内存中是一个非常糟糕的主意,尽管这是可能的。哦,当然有些系统实际上只有 12+GB 的 RAM,但这也不是重点。 )
  • @MethodMan,我很害怕 :)。

标签: c# linq collections dataset large-files


【解决方案1】:

当我不得不做这样的事情之前,我通过拥有一个包含字典列表的容器对象来处理它。当时我认为限制将/应该是 2^32 个元素,但是在获得 2^32 个元素之前就抛出了超出集合的异常并且仍然​​有许多 GB 的内存。假设你想要一个字典,这样的东西应该可以工作,直到你真的用尽所有物理和虚拟内存......你的可能解决方案如下......我记得几年前我工作时服务器实际上有 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 :(  
            }  
         }  
    }  

【讨论】:

    【解决方案2】:

    经过一些讨论,最好的办法是读取文件,处理它,然后处理所有其余部分,只保留结果。

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

    【讨论】:

      【解决方案3】:

      看这个:

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

      您可以存储任何您想要的东西 - 没有停顿。 大集合的问题是: 一种。它们的设计并不是为了容纳很多条目(即字典永远不会缩小到零大小) 湾。当您有太多对象时,您会遇到 GC 停顿/暂停

      请参阅上面的链接 - 我们所做的是从 GC 中“隐藏”数据,如文章中所述。这样您就可以使用 LocalCache 类作为字典来存储数百万个对象。

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

      【讨论】:

        猜你喜欢
        • 2020-11-04
        • 2016-09-28
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 2016-12-30
        • 2022-01-06
        • 2010-11-22
        相关资源
        最近更新 更多