我想优化一个并发集合,试图最小化读取的锁争用。第一遍使用的是链接列表,这允许我只锁定写入,而许多同时读取可以继续畅通。这使用一个自定义的IEnumerator
到产量下一个链接值。一旦我开始比较了集合迭代纯List<T>
我发现我实现一半左右的速度(对于from x in c select x
上的1 * M *项目的集合,我得到24MS为List<T>
和49ms我的集合)。寻找IEnumerable/IEnumerator更快的实现
所以我想我会使用ReaderWriteLockSlim
并牺牲读取的一点争论,所以我可以使用List<T>
作为我的内部存储。由于我必须在迭代开始时捕获读锁,并在完成时释放读锁,因此我首先对我的IEnumerable
,foreach进行了内部List<T>
的良率模式。现在我只得到66ms。
我偷偷看看List实际做了什么,它使用T[]
的内部存储和自定义IEnumerator
,它向前移动索引并返回当前索引值。现在,手动使用T[]
作为存储意味着更多的维护工作,但是,我正在追逐微秒。
然而,即使模仿IEnumerator
移动索引的阵列,我能做的最好的是大约~38ms。那么,究竟是什么给了它的秘诀,或者迭代器的更快实现呢?
更新:原来我的主要速度罪魁祸首是运行调试编译,而List<T>
显然是一个发布编译。在发布中,我的实现仍然比List<T>
慢,尽管单声道现在更快。
我从朋友那里得到的另外一个建议是BCL更快,因为它位于GAC中,因此可以通过系统预编译。将不得不在GAC中进行测试来测试该理论。
@Arne:我添加了一个你可能想尝试的编辑。事实上,如果你不需要检测并发修改,你应该能够*击败'List'的性能:) –
2009-11-18 07:36:34