如何以最有效的方式迭代和删除hashset中的元素

时间:2015-03-17 12:58:12

标签: c# .net loops hashset

好的,我想出了什么,但我想知道这是最有效的方式。我需要为ram内存问题做这件事。

HashSet<string> hsLinks = new HashSet<string>();
List<string> lstSortList = new List<string>();

// fill hashset with millions of records

while (true)
{
    string srLastitem = "";
    foreach (var item in hsLinks)
    {
        srLastitem = item;
        break;
    }
    lstSortList.Add(srLastitem);
    hsLinks.Remove(srLastitem);
    if (hsLinks.Count == 0)
        break;
}

c#.net 4.5.2 wpf application

2 个答案:

答案 0 :(得分:5)

您似乎正在尝试将项目从HashSet移至List。如果是这种情况,只需使用List.AddRange移动一次,然后使用HashSet.Clear清空HashSet

lstSortList.AddRange(hsLinks);
hsLinks.Clear();

如果(如Vajura建议的那样)你担心持有2份引用 *,你可以改为移动批次而不是单个项目:

const int batchSize = 1000;
var batch = new string[batchSize];
do
{
    var batchIndex = 0;
    foreach (var link in hsLinks.Take(batchSize))
    {
        batch[batchIndex] = link;
        batchIndex++;
    }

    if (batchIndex < batchSize)
    {
        batch = batch.Take(batchIndex).ToArray();
    }

    hsLinks.ExceptWith(batch);
    lstSortList.AddRange(batch);
} while (hsLinks.Any());

使用适当大小的批次来解决内存问题。


*注意:引用的大小为4或8个字节(分别为32位和64位)。当你将字符串(它们是.Net中的引用类型)添加到你没有复制它们的列表时,只有引用(这些引用几乎可以忽略不计)。

答案 1 :(得分:2)

如果您尝试将项目从hsLinks移至lstSortList(之后清除hsLinks),则可以使用此List<T>.AddRange()

lstSortList.AddRange(hsLinks);
hsLinks.Clear();