System.Collections.SortedList has a SetByIndex method that is cheap, O(1) owing to the nature of the data structure. The generic version of this class does not have a SetByIndex method. I am looking for the equivalent operation for the SortedList implementation in System.Collections.Generic.
Both classes implement a dictionary using sorted arrays. Since the underlying structure is an array, the entries can be efficiently accessed by index. The non-generic version also offers a GetByIndex method that retrieves a value by index (as opposed to key). The generic SortedList also supports retrieval by index through the .Values property. When I try to modify an element through the .Values property, I get an exception that says "This operation is not supported on SortedList nested types because they require modifying the original SortedList."
I'm not an expert on object-oriented design, but why not just let me modify the value through the "nested type" returned by the SortedList?
For this project, I am on .NET 4.0. I need the SortedList so I can iterate through the items in sorted order. Based on profiling, the very most expensive call tree in the program involves iterating through the items in a bunch of small SortedLists by index (and so in sort order by key) and modifying certain values. Currently to perform that value modification step, I have to assign using the key, which involves log(n) string comparison operations to locate the proper slot than simply assigning the value by index (i.e. SetByIndex) which would be zero comparisons. I am not changing the key so nothing would affect the position of the value in the array.
19% (exclusive) total program time spent in System.String.CompareTo(string), almost all of which is from the method that modifies the values.
Sample code to illustrate:
class Container
{
readonly System.Collections.Generic.SortedList<string, MapEntryValueType> map;
void Merge(IncomingData data)
{
for(int i=0; i < map.Count; i++)
if(data.ExamineKeyForMatch(map.Keys[i])) //O(1)
{
MapEntryValueType entry = map.Values[i]; //O(1)
entry.something = data.something;
//map.Values[i] = entry; //O(1) no can do, error "This operation is not supported..."
//map.SetByIndex(i, entry); //O(1) no can do, no such method
map[map.Keys[i]] = entry; //O(log n) yucky and slow but works
}
}
}