I using List<T>
in my project, this list contains hundreds of entries. I am using List.Contains method quite a lot and this is hurting performance, I replaced the List with dictionary but it resulted in memory bottleneck, thus made performance even worst. Is there a better solution that one can suggest for searching in List? Is there a replacement of HashSet<T>
in C# 2.0 or some other way that is better both memory and speed wise?
Asked
Active
Viewed 6,349 times
8

isekaijin
- 19,076
- 18
- 85
- 153

FIre Panda
- 6,537
- 2
- 25
- 38
-
What are you trying to do? What are the list constraints? You have not provided the kind of information that a recommendation needs to be based on. – Oded May 12 '11 at 12:14
-
List
Iam using, and List.Contains complexity is O(N), so it is hurting performance. – FIre Panda May 12 '11 at 12:24 -
What kind of data are you holding in this list? Hundreds of entries is not that much normally. Regardless, you don't explain what you are doing with the list. Saying `Contains` means nothing. – Oded May 12 '11 at 12:26
-
Only a few hundreds? And this is causing problems? Unless you are nesting multiple loops I can't see how this would be a performance issue. – Oded May 12 '11 at 12:28
-
foreach (Entity entity in _lstEntities) { if (entitiesExt.Contains(entity.EntityId)) continue; } Profiler shows this code took 437 sec in all. – FIre Panda May 12 '11 at 12:37
-
Try this: `foreach (Entity entity in _lstEntities) { if (entitiesExt.Contains(entity)) continue; }`. You are comparing each entity to an entityId, not to another entity. – Oded May 12 '11 at 12:39
-
entitiesExt is of List
not List – FIre Panda May 12 '11 at 12:52. -
3You really should be posting all of this code in your question. – Oded May 12 '11 at 12:52
-
@Abdul: If that takes 437 seconds and your list only contains hundreds of elements, there is something very wrong with your computer. – recursive May 12 '11 at 13:13
-
Hahaha, nice joke, I am talking about overall it takes 437 seconds, and that method is called thousands time. List.Contains is of O(N) in searching. – FIre Panda May 12 '11 at 14:08
3 Answers
7
A Dictionary<T,bool>
can be used in place of a HashSet<T>
. Whether you add items with a value of True or False is a coin toss, the value is not relevant.
It's more cumbersome than a HashSet<T>
, and not quite a light-weight, but it's certainly better than a List<T>
.

Tergiver
- 14,171
- 3
- 41
- 68
-
OP says: `I replaced the List with dictionary but it resulted in memory bottleneck` – marsh-wiggle Dec 01 '20 at 15:54
3
public class HashCollection <T> : ICollection <T>
{
private Dictionary<T, bool> _innerDictionary;
public HashCollection()
{
_innerDictionary = new Dictionary<T, bool>();
}
void ICollection <T>.Add(T item)
{
AddInternal(item);
}
private void AddInternal(T item)
{
_innerDictionary.Add(item, false);
}
public bool Add(T item)
{
if (_innerDictionary.ContainsKey(item))
return false;
AddInternal(item);
return true;
}
public void Clear()
{
_innerDictionary.Clear();
_innerDictionary = new Dictionary<T, bool>();
}
public bool Contains(T item)
{
return _innerDictionary.ContainsKey(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
_innerDictionary.Keys.CopyTo(array, arrayIndex);
}
public int Count
{
get { return _innerDictionary.Keys.Count; }
}
public bool IsReadOnly
{
get
{
return false;
}
}
public bool Remove(T item)
{
return _innerDictionary.Remove(item);
}
public IEnumerator<T> GetEnumerator()
{
return _innerDictionary.Keys.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

George Lica
- 1,798
- 1
- 12
- 23
2
If you can live withthe requirement that .Net 3.5 framework be installed, you can use the HashSet from .Net 3.5 (System.Core.dll) in a 2.0 project.
See this question: Using HashSet in C# 2.0, compatible with 3.5
If that's a no go, I would use dictionary instead.