【发布时间】:2011-11-04 00:35:35
【问题描述】:
我有一种情况,我需要执行许多获取/设置,在性能分析之后,这是我的应用程序中更昂贵的部分之一。最初我使用的是字典,但在内部切换到锯齿状数组,这给它带来了显着的性能提升,但我仍然想看看是否有一种方法可以在不放弃漂亮且可用的语法的情况下提高此代码的性能。
注意调用 Convert.ToInt32 比调用强制转换要昂贵得多,并且由于通用约束 TStatus : int 不适用于枚举,我必须将其实现为抽象类,如果这个集合能够使用任何开箱即用的枚举。
我还尝试为 IEnumerable 实现 yield,但这实际上比仅填充列表要慢。
public abstract class LoanStatusVectorOverTime<TStatus> : ILoanStatusVectorOverTime<TStatus>
where TStatus: struct
{
protected static readonly TStatus[] LoanStatusTypes = (TStatus[])Enum.GetValues(typeof(TStatus));
protected static readonly int LoanStatusCount = Enum.GetValues(typeof(TStatus)).Length;
protected const int MonthsSinceEventCount = 25;
private readonly object SYNC = new object();
protected double[,] VectorDictionary { get; set; }
public LoanStatusVectorOverTime()
{
this.VectorDictionary = new double[LoanStatusCount, MonthsSinceEventCount];
}
public double this[TStatus status, int monthsSince]
{
get
{
if (monthsSince >= MonthsSinceEventCount)
return 0;
return VectorDictionary[GetKeyValue(status), monthsSince];
}
set
{
if (monthsSince >= MonthsSinceEventCount)
return;
VectorDictionary[GetKeyValue(status), monthsSince] = value;
}
}
public double SumOverStatus(TStatus status)
{
double sum = 0;
foreach (var fromStatus in LoanStatusTypes)
{
int i = 0;
while (i < MonthsSinceEventCount)
{
sum += VectorDictionary[GetKeyValue(fromStatus), i];
i++;
}
}
return sum;
}
public IEnumerator<KeyValuePair<Tuple<TStatus, int>, double>> GetEnumerator()
{
List<KeyValuePair<Tuple<TStatus, int>, double>> data = new List<KeyValuePair<Tuple<TStatus, int>, double>>();
foreach (var fromStatus in LoanStatusTypes)
{
int i = 0;
while (i < MonthsSinceEventCount)
{
var val = VectorDictionary[GetKeyValue(fromStatus), i];
if (val != default(double))
data.Add(new KeyValuePair<Tuple<TStatus, int>, double>(new Tuple<TStatus, int>(fromStatus, i), val));
i++;
}
}
return data.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
protected abstract int GetKeyValue(TStatus status);
protected abstract ILoanStatusVectorOverTime<TStatus> Initalize();
public ILoanStatusVectorOverTime<TStatus> Copy()
{
var vect = Initalize();
foreach (var fromStatus in LoanStatusTypes)
{
int i = 0;
while (i < MonthsSinceEventCount)
{
vect[fromStatus, i] = VectorDictionary[GetKeyValue(fromStatus), i];
i++;
}
}
return vect;
}
public double SumOverAll(int monthsSince = 1)
{
double sum = 0;
foreach (var status in LoanStatusTypes)
{
sum += this[status, monthsSince];
}
return sum;
}
}
public class AssetResolutionVector : LoanStatusVectorOverTime<AssetResolutionStatus>
{
protected override int GetKeyValue(AssetResolutionStatus status)
{
return (int)status;
}
protected override ILoanStatusVectorOverTime<AssetResolutionStatus> Initalize()
{
return new AssetResolutionVector();
}
}
var arvector = new AssetResolutionVector();
arvector[AssetResolutionStatus.ShortSale, 1] = 10;
【问题讨论】:
-
能否也给
ILoanStatusVectorOverTime的代码 -
公共接口 ILoanStatusVectorOverTime
: IEnumerable , double>> where TStatus: struct { double this[TStatus status, int monthsSince] { get;放; } double SumOverAll(int monthsSince = 1); ILoanStatusVectorOverTime Copy(); } -
@Jason Lind:您可以通过单击“编辑”按钮为您的问题添加额外的代码。 (这样阅读界面会容易得多。)
-
我没有看到锯齿状数组
标签: c# performance generics collections