如何以最有效的方式从哈希集中迭代和删除元素

How to iterate and remove elements from hashset most effective way

好的,这是我想到的,但我想知道这是不是最有效的方法。我需要为 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 应用程序

如果您尝试将项目从 hsLinks 移动到 lstSortList(然后清除 hsLinks),这就是您要使用 List<T>.AddRange() 的地方

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

您似乎正试图将项目从 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 中的引用类型)添加到列表中时,您并没有复制它们,只有引用(几乎可以忽略不计)。