【问题标题】:LINQ Join on very large dictionaries / out of memory exceptionLINQ加入非常大的字典/内存不足异常
【发布时间】:2015-06-22 11:37:44
【问题描述】:

我有两个字典,我正在尝试加入并将匹配的索引保存在单独的字典中,如下所示:

public class MatchedPairs
    {
        public List<int> index1;
        public List<int> index2;

        public MatchedPairs()
        {
            this.index1 = new List<int>();
            this.index2 = new List<int>();
        }
    }

Dictionary<int, string> file1Dictionary = new Dictionary<int, string>();
Dictionary<int, string> file2Dictionary = new Dictionary<int, string>();

//Fill dictionaries with data from flat files
//...

var matchedKeys = file1Dictionary.Join(file2Dictionary, x => x.Value, y => y.Value, (x, y) => new { k1 = x.Key, k2 = y.Key });

Dictionary<int, MatchedPairs> matches = new Dictionary<int, MatchedPairs>(); 

foreach (var match in matchedKeys)
{
    matches.index1.Add(match.k1);
    matches.index2.Add(match.k2);
}

我收到一个

内存不足异常

执行此代码时,因为 file1Dictionaryfile2Dictionary 对象中有数百万个条目。

我可以做些什么来匹配内存/C# 中的这些大对象。我的替代方法是将数据加载到 SQL 数据库中并在那里进行连接。谢谢。

【问题讨论】:

  • 如果你能在数据库中完成它是最好的选择。
  • 您是否将其作为 64 位应用程序运行?
  • 其实可以把字典加载到内存中吗?是join会抛出内存不足异常吗?
  • 这里有一些关于类似问题的信息stackoverflow.com/a/20643387/4019425。像这样进行预分配可能会解决问题: Dictionary file1Dictionary = new Dictionary(40000000); (将限制设置为 40000000 个条目,如果需要则增加)
  • 按照@Enigmativity 的建议以 64 位运行应用程序,并将 gcAllowVeryLargeObjects 设置为 true(检查此 stackoverflow.com/questions/8641888/…

标签: c# linq


【解决方案1】:

我认为你的字典应该是 Dictionary 匹配(不是整数)。

    class Program
    {
        static void Main(string[] args)
        {

           Dictionary<int, string> file1Dictionary = new Dictionary<int, string>();
           Dictionary<int, string> file2Dictionary = new Dictionary<int, string>();

           //Fill dictionaries with data from flat files
           //...
           Dictionary<string, List<int>> reverseDict1 = file1Dictionary.Keys.AsEnumerable()
               .Select(x => new { value = x, keys = file1Dictionary[x] })
               .GroupBy(x => x.keys, y => y.value)
               .ToDictionary(x => x.Key, y => y.ToList());

           Dictionary<string, List<int>> reverseDict2 = file1Dictionary.Keys.AsEnumerable()
               .Select(x => new { value = x, keys = file2Dictionary[x] })
               .GroupBy(x => x.keys, y => y.value)
               .ToDictionary(x => x.Key, y => y.ToList());

           Dictionary<string, MatchedPairs> matches = new Dictionary<string, MatchedPairs>();
           foreach(string key in reverseDict1.Keys)
           {
               matches.Add(key, new MatchedPairs(reverseDict1[key], reverseDict2[key]));
           }

        }
    }
    public class MatchedPairs
    {
        public List<int> index1 { get; set; }
        public List<int> index2 { get; set; }

        public MatchedPairs(List<int> l1, List<int> l2)
        {
            this.index1 = new List<int>(l1);
            this.index2 = new List<int>(l2);
        }
    }

【讨论】:

  • 这究竟是如何修复 OOM 异常的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
  • 2010-10-05
  • 1970-01-01
相关资源
最近更新 更多