前言:我问这个问题只是因为我没有一个环境(足够大的数据集+计算能力)来以可靠的方式测试它。
问题:给定一个ConcurrentBag<T>
,加载了数十亿个项目,由单个线程访问/使用,它的性能与List<T>
相似吗?换句话说,ConcurrentBag<T>
上的枚举比List<T>
上的枚举性能更好还是更差?
前言:我问这个问题只是因为我没有一个环境(足够大的数据集+计算能力)来以可靠的方式测试它。
问题:给定一个ConcurrentBag<T>
,加载了数十亿个项目,由单个线程访问/使用,它的性能与List<T>
相似吗?换句话说,ConcurrentBag<T>
上的枚举比List<T>
上的枚举性能更好还是更差?
3条答案
按热度按时间pw9qyyiw1#
ConcurrentBag<T>
不可避免地会比List<T>
性能差。虽然您将只从单个线程访问它,但该结构仍然需要适当的机制来防止出现并发访问时可能出现的争用危险。如果您将在开始枚举之前 * 从单个线程加载集合,则可以使用
ConcurrentBag(IEnumerable<T>)
构造函数来避免性能开销,而不是通过其Add
方法单独添加每个项。ConcurrentBag<T>
为枚举提供“即时快照”语义;请参阅GetEnumerator
方法的备注。当您从foreach
循环访问ConcurrentBag<T>
时,它会首先将其全部内容复制到一个普通的List<T>
中,然后在其上枚举。每次在循环中使用它时,这将导致大量的性能开销(计算和内存方面)。如果您的场景是列表将由多个线程填充,但只由一个线程读取,那么您应该在编写器完成后立即将其转换为
List<T>
。yacmzcpb2#
数十亿的项目和列表或并发包?这是一个“不去”。
就性能而言,请尝试以下测试添加:(您可以随意修改以测试其他操作)
我的输出:
使用的CPU:英特尔酷睿i7- 2600@3.4 GHz,
使用内存:16 GB
还可以查看this answer的限制。
xzv2uavs3#
但是,如果您需要删除项目,ConcurrentBag比List要快得多