我有一个以下列方式定义的类。接口和具体类型都有一个Type参数,我希望它是double,int,decimal或DateTime。我添加了IComparable的where约束但是这个类做了一些重的数字提升所以我想避免装箱和拆箱。类定义如下:
public interface INumericClass<T1, T2> where T1:IComparable
where T2:IComparable
{
void DoLongNumericOperation();
}
public class NumericClass<T1, T2> : INumericClass<T1, T2> where T1:IComparable
where T2:IComparable
{
private IList _innerArray1 = new T1[1000000];
private IList _innerArray2 = new T2[1000000];
public void DoLongNumericOperation()
{
for(int i = 0; i < _innerArray1.Count; i++)
{
// some computation goes on in here
// for example, it could be
double aConstant = 123.45;
double aScalar = 56.7;
_innerArray1[i] = (Convert.ToDouble(_innerArray1[i]) * aConstant + aScalar);
_innerArray2[i] = (Convert.ToDouble(_innerArray2[i]) * aConstant + aScalar);
}
}
}
这些类将在调用代码时声明和使用,如下所示
var numeric = new NumericClass<int, double>();
numeric.DoLongNumericComputation();
现在我内部处理多种类型的方法是将T转换为double。但是我担心因为我已经指定T是IComparable类型的类型参数,所以取消装箱/装箱正在进行中。此外,DateTime还提供额外的开销。在这种情况下我正在做的是将.Ticks
属性转换为double并对其进行操作。
我欢迎任何关于CLR内幕发生的信息,以及改进性能的建议,例如API更改,以强类型化每个数字操作以提高性能和内存使用。
编辑:我还应该添加上面的实现是次优的,就像你声明NumericClass一样,它开始抛出从Tx转换为double。虽然我不确定,但我只能假设通过IComparable进行投射。
答案 0 :(得分:2)
如果没有更完整的例子,我可以推荐这里。
public interface IConvertToDouble<T>
where T : IComparable
{
double Convert(T input);
T ConvertBack(double input);
}
public class NumericClass<T, U>
where T : IComparable,
U : IComparable
{
private IConvertToDouble<T> _tConverter;
private IConvertToDouble<U> _uConverter;
private List<T> _internalTs;
private List<U> _internalUs;
public NumericClass(IConvertToDouble<T> tConverter, IConvertToDouble<U> uConverter)
{
_tConverter = tConverter;
_uConverter = uConverter;
_internalTs = new List<T>();
_internalUs = new List<U>();
}
public void DoLongNumericOperation()
{
for(int i = 0; i < innerArray.Length; i++)
{
// some computation goes on in here
// for example, it could be
double aConstant = 123.45;
double aScalar = 56.7
_internalTs[i] = _tConverter.ConvertBack(_tConverter.Convert(_internalTs[anIndex]) * aConstant + aScalar);
_internalUs[i] = _uConverter.ConvertBack(_uConverter.Convert(_internalUs[anIndex]) * aConstant + aScalar);
}
}
}
现在您不需要在NumericClass中转换通用对象或具有特定于类型的逻辑。
答案 1 :(得分:1)