【发布时间】:2011-04-25 01:48:52
【问题描述】:
几天前,我在 SO 上回答了an interesting question 关于HashSet<T>。一个可能的解决方案涉及克隆哈希集,在我的回答中,我建议做这样的事情:
HashSet<int> original = ...
HashSet<int> clone = new HashSet<int>(original);
虽然这种方法很简单,但我怀疑它的效率很低:新的HashSet<T> 的构造函数需要分别添加原始哈希集中的每个项目,并检查它是否已经存在。这显然是在浪费时间:由于源集合是ISet<T>,因此保证不包含重复项。应该有办法利用这些知识...
理想情况下,HashSet<T> 应该实现ICloneable,但不幸的是事实并非如此。我还检查了 Reflector,如果源集合是一个哈希集,HashSet<T> 构造函数是否做了一些特定的事情,但它没有。它可能可以通过在私有字段上使用反射来完成,但这将是一个丑陋的黑客......
那么,有没有人想出一个聪明的解决方案来更有效地克隆哈希集?
(请注意,这个问题纯属理论,我不需要在实际程序中这样做)
【问题讨论】:
-
嗯,很好的问题,只是很好奇,我们关心的理论效率低下是什么?我对抽象数据类型的顺序表示法生疏了,但是检查目标哈希集中是否存在不是一个简单的 O(1) 碰撞测试吗?我同意从信息的角度来看它可能会“更好”,但我们可以限制它吗?它会很重要吗?
-
我怀疑他们没有 HashSet
(ISet ) 构造函数是因为任何类都可以实现 ISet ,也许很糟糕;这意味着 ISet 的存在并不能保证没有重复 -
@Steve Ellinger,你可能是对的。但是,他们本可以提供一个 HashSet
(HashSet ) 构造函数... -
其实,我很好奇的是为什么他们没有实现 ICloneable,是不是因为任何实现都不会比你最终在你提到的答案中调用的构造函数更有效;因此,当功能已经可用时,为什么还要打扰。您的复制构造函数也可以这样说。当然,鉴于您对“并检查它是否不存在”的评论,这似乎不合理。嗯。
-
即使是反序列化器也不做任何假设,而是使用 AddIfNotPresent()。好主意,文化可能已经改变。这是不行的。质疑是否需要先克隆。昂贵的操作应该很昂贵。很棒的 API 设计。
标签: .net performance clone hashset