【发布时间】:2015-07-23 13:37:04
【问题描述】:
我有一个类Foo,其中包含一个对象列表:List<Bar>。每个Bar 都有一个可以对其进行排序的属性(TimeSpan 类型,表示持续时间),Bar 是一个不可变对象——也就是说,持续时间不会随着算法的运行而改变。目前,对于每个Foo,我还维护Bar,如果要订购它,它将在列表中排在第一位(即持续时间最短的Bar)。像这样的:
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);
}
}
此类Foo 用于处理性能(速度)至关重要的算法。内存很重要,但不如速度重要。有 n 个Foos 的列表,每个列表最多有 m 个Bars。到目前为止,这门课一直让我受益匪浅。我现在希望为用户提供多种选择,这意味着我需要提供对列表中前几个Bars 的随机访问。
因此,我想按顺序存储我的Bars,以便我可以按顺序按索引访问它们。在我的Bar 类中,我实现了IComparable 以允许比较Bars 的持续时间,但我一直在选择合适的数据类型。我查看了System.Collections.SortedList,但(除非我错了)这似乎是按键引用元素,因为它实现了IDictionary。 我可以使用什么集合来维护我的对象,使它们保持排序状态,并且可以按索引顺序遍历它们?
【问题讨论】:
-
试试
SortedSet但注意它不允许重复。 -
@AdamHouldsworth 不认为它与“性能”有关
-
我个人会在算法的使用点订购它。维护一个标志来说明它是否需要根据自上次排序后是否有添加来进行排序,然后让调用者有责任在运行算法之前进行排序。归根结底,排序的实现是特定于该算法的,因此我认为将责任转移给它没有问题。
-
@AlexanderKozlov 我知道,但我想了解为什么在此算法之前不能使用像
var sorted = list.OrderBy(_ => _).ToArray()这样简单的东西。如果不知道发生了多少插入、列表有多大、在排序之间或 w/e 之间调用该算法的频率,我们就无法建议一个实现。 -
这是您必须决定最佳折衷方案的事情之一。如果您想要一个排序列表,具有索引访问和插入(可能删除)项目的能力,同时保持排序顺序,那么至少其中一个操作最终会变慢,以便让其他操作更快。您需要弄清楚用法会是什么样子。你会插入很多吗?多读书?随机阅读还是按顺序阅读?名单有多大?等等。
标签: c# .net performance sorting icomparable