并发集合是否缓存枚举器快照?
Do concurrent collections cache the enumerator snapshots?
如果我理解正确,那么并发集合会创建一个快照作为 foreach
循环中使用的 Enumerator
的源,这需要锁定。
他们每次都缓存快照或锁定吗?这对性能有潜在影响吗?我对微观测量持怀疑态度,因为它们很容易得出错误的结论,我正在尝试了解其内部运作方式。
谢谢!
不,它似乎没有缓存。这是来自 ConcurrentBag<T>
:
的代码
public IEnumerator<T> GetEnumerator()
{
if (m_headList != null)
{
bool lockTaken = false;
try
{
FreezeBag(ref lockTaken);
return ToList().GetEnumerator();
}
finally
{
UnfreezeBag(lockTaken);
}
}
return new List<T>().GetEnumerator();
}
private List<T> ToList()
{
List<T> list = new List<T>();
for (ThreadLocalList threadLocalList = m_headList; threadLocalList != null; threadLocalList = threadLocalList.m_nextList)
{
for (Node node = threadLocalList.m_head; node != null; node = node.m_next)
{
list.Add(node.m_value);
}
}
return list;
}
如果我理解正确,那么并发集合会创建一个快照作为 foreach
循环中使用的 Enumerator
的源,这需要锁定。
他们每次都缓存快照或锁定吗?这对性能有潜在影响吗?我对微观测量持怀疑态度,因为它们很容易得出错误的结论,我正在尝试了解其内部运作方式。
谢谢!
不,它似乎没有缓存。这是来自 ConcurrentBag<T>
:
public IEnumerator<T> GetEnumerator()
{
if (m_headList != null)
{
bool lockTaken = false;
try
{
FreezeBag(ref lockTaken);
return ToList().GetEnumerator();
}
finally
{
UnfreezeBag(lockTaken);
}
}
return new List<T>().GetEnumerator();
}
private List<T> ToList()
{
List<T> list = new List<T>();
for (ThreadLocalList threadLocalList = m_headList; threadLocalList != null; threadLocalList = threadLocalList.m_nextList)
{
for (Node node = threadLocalList.m_head; node != null; node = node.m_next)
{
list.Add(node.m_value);
}
}
return list;
}