我遇到了一个非常奇怪的问题。因此,背景是我们在 WordContentControl
和自定义对象之间建立了映射,我们使用该对象来存储与该控件内的内容相关的一些信息。我们使用 aSortedList<ContentControl, OurCustomObject>
来维护这个映射。SortedList 部分对于能够找到下一个/上一个内容控件以及能够快速访问与内容控件关联的对象很有用。
为了进行设置,我们执行以下操作:
var dictOfObjs = Globals.ThisAddIn.Application.ActiveDocument.ContentControls
.Cast<ContentControl>()
.ToDictionary(key => key, elem => new OurCustomObject(elem));
var comparer = Comparer<ContentControl>
.Create((x, y) => x.Range.Start.CompareTo(y.Range.Start));
var list = new SortedList<ContentControl, OurCustomObject>(dictOfObjs, storedcomparer);
这似乎工作得很好,但我最近在一个包含约 5000 个内容控件的文档上尝试了它,它减慢到绝对爬行(实例化 SortedList 3 分钟以上)。
所以这已经够奇怪了,但更多的奇怪还在后面。我添加了一些日志记录来弄清楚发生了什么,ContentControl
并发现在列表中使用它们之前记录每个的开始可以加快大约 60 倍。(是的,添加日志记录加快了速度!)。这是更快的代码:
var dictOfObjs = Globals.ThisAddIn.Application.ActiveDocument.ContentControls
.Cast<ContentControl>()
.ToDictionary(key => key, elem => new OurCustomObject(elem));
foreach (var pair in dictOfObjs)
{
_logger.Debug("Start: " + pair.Key.Range.Start);
}
var comparer = Comparer<ContentControl>
.Create((x, y) => x.Range.Start.CompareTo(y.Range.Start));
var list = new SortedList<ContentControl, OurCustomObject>(dictOfObjs, storedcomparer);
SortedList 的构造函数调用Array.Sort<TKey, TValue>(keys, values, comparer);
字典的键和值。我不明白为什么事先在循环中访问 Range 对象会加快速度。也许与访问它们的顺序有关?foreach 循环将按照它们在文档中出现的顺序访问它们,而 Array.Sort 将四处跳跃。
编辑:当我说 SortedList 时,我的意思是System.Collections.Generic.SortedList<TKey, TValue>
. 这是我正在使用的构造函数的代码:
public SortedList(IDictionary<TKey, TValue> dictionary, IComparer<TKey> comparer)
: this((dictionary != null ? dictionary.Count : 0), comparer) {
if (dictionary==null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
dictionary.Keys.CopyTo(keys, 0);
dictionary.Values.CopyTo(values, 0);
Array.Sort<TKey, TValue>(keys, values, comparer);
_size = dictionary.Count;
}