I have a class Foo
which contains a list of objects: List<Bar>
. Each Bar
has a property which they can be ordered on (of type TimeSpan
, representing a duration), and Bar
is an immutable object - that is, the duration does not change over the running of the algorithm. At the moment, for each Foo
I also maintain the Bar
that would be first in the list if it were to be ordered (i.e. the Bar
of shortest duration). Something like this:
public class Foo
{
public List<Bar> AllBars { get; set; }
public Bar FirstBar { get; set; }
public Foo (Bar bar)
{
FirstBar = bar;
AllBars = new List<Bar>() { bar };
}
public AddBar(Bar bar)
{
if(bar.Duration < FirstBar.Duration)
{
FirstBar = bar;
}
AllBars.Add(bar);
}
}
This class Foo
is used in an algorithm where processing performance (speed) is critical. Memory is important but not as much as speed. There is a list of n Foo
s, each of which has up to m Bar
s. This class has served me well up until this point. I now wish to offer the user several choices, meaning I will need to provide random access to the first few Bar
s in the list.
I would thus like to store my Bar
s in order so that I can access them by index in order. In my Bar
class I implemented IComparable
to allow Bar
s to be compared on duration but I am stuck at choosing an appropriate data type. I looked at System.Collections.SortedList
but (unless I am wrong) this appears to reference elements by key as it implements IDictionary
. What collection could I use that would maintain my objects such that they stay sorted, and such that they are traversable in order of index?
List<T>
using itsSort
method? This will need calling after every insert, but allows you to also suppress sorting if you know you're about to add a batch of items. You could decorateList<T>
with your own implementation that does the sorting call for you so from the outside you're still using anIList<T>
. – BasidiosporeSortedSet
but note that it does not allow duplicates. – CalabashSortedList
.SortedSet
doesnt allow you to get element by index – AnastomoseSortedList
and useDuration
as the key rather then implementing a comparator? – CalabashSortedList
norSortedSet
achieve that. I don't yet see why sorting a regular list isn't working, or where the performance degradation comes in. – BasidiosporeAllBars[2]
or do you just need to maintain order when iterating withforeach
? – CalabashSortedList
would perform extremely poorly. It would make every addition to the list quite expensive. – MulhollandList
wasnt intended to store elements in a sorted order. So each time you call.Sort()
it sorts whole array. ButSorted*
classes maintain elements in a sorted way resulting in faster insertions – Anastomosevar sorted = list.OrderBy(_ => _).ToArray()
can't be used prior to this algorithm. We can't suggest an implementation without knowing how many insertions occur, how big the list gets, how often this algorithm is called between sorts or w/e. – BasidiosporeDuration
change over the life of an object? If so then re-sorting periodically is the only option (either explicitly or implicitly by the collection). – CalabashBar
at a time. The provided code only compares the inserted item once, to see if FirstBar needs updating. Re: ordering it at point of use - I should have pointed out there are m objects of typeFoo
. – CalvariaFoo
(of about 100 000) ends up having 50 to 100Bar
s. I will use the first 10 or so that need to be accessed randomly (they are options for the user). And no,Bar
s are immutable - duration never changes. I will update the question with this information. – CalvariaSortedList<Bar, object>
where you do not use the value part. Add withyourSortedList.Add(yourBar, null)
in O(n) time (the list will have to move "up" all entries after the point where you insert). Retrieve thei
th entry in O(1) time withyourSortedList.Keys[i]
. EDIT: You will not be able to have duplicates in yourSortedList<,>
, so two members can notCompareTo
each other with return value zero. – ThirtyBar
s get removed? – EustisBinarySearch
on inserts (and if adding a large number in one go, a plainAddRange
followed by aSort
) would be the way to go as while it's expensive, the read-only accesses are as fast as with a list. – ChuckleheadBar
items in order of duration and accessed in order of duration. Insertion order is unimportant. – CalvariaBar
s never get removed, and they are also immutable. – Calvaria