凡双重Typeparam的通用类型的限制 - 拳击/拆箱? [英] Where constraint on Generic Type with Double Typeparam - boxing/unboxing?

查看:138
本文介绍了凡双重Typeparam的通用类型的限制 - 拳击/拆箱?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个以下列方式定义的类。接口和具体类型都有一个类型参数,我期望它是一个double,int,decimal或DateTime。我已经添加了IComparable的where约束,但是这个类做了一些重的数字提升,所以我想避免装箱和拆箱。类定义如下:

  public interface INumericClass< T1,T2> T1:IComparable 
其中T2:IComparable
{
void DoLongNumericOperation();
}

公共类NumericClass< T1,T2> :INumericClass< T1,T2>其中T1:IComparable
其中T2:IComparable
{
私有IList _innerArray1 =新T1 [1000000];
私人IList _innerArray2 =新T2 [1000000];
public void DoLongNumericOperation()
{
for(int i = 0; i< _innerArray1.Count; i ++)
{
//一些计算进行到这里
//例如,它可以是
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加倍。不过我担心的是,既然我已经指定T是一个IComparable类型的参数,那么拆箱/装箱正在进行。另外DateTime提供额外的开销。我在这种情况下所做的是将 .Ticks 属性转换为双精度值并对其进行操作。

我欢迎任何关于CLR背后的情况的信息,以及改进性能的建议,例如API更改,以强制键入每个数字操作以改善性能和内存使用情况。

编辑:我还应该添加上面的实现是次优的,就好像你声明了NumericClass它开始投掷从Tx转换到double 。尽管我不确定,但我只能假设它通过IComparable进行投射。

解决方案

没有看到更完整的示例,这里是我可以推荐的。

  public interface IConvertToDouble< T> 
其中T:IComparable
{
double转换(T输入);
T ConvertBack(双输入);
}

公共类NumericClass< T,U>
其中T:IComparable,
U:IComparable
{
private IConvertToDouble< T> _tConverter;
私人IConvertToDouble< U> _uConverter;
私人列表< T> _internalTs;
私人列表< U> _internalUs;

public NumericClass(IConvertToDouble< T> tConverter,IConvertToDouble< U> u转换器)
{
_tConverter = tConverter;
_uConverter = uConverter;
_internalTs =新列表< T>();
_internalUs =新列表< U>();

$ b $ public void DoLongNumericOperation()
{
for(int i = 0; i< innerArray.Length; i ++)
{
//一些计算在这里进行
//例如,它可以是
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中强制转换泛型对象或使用特定类型的逻辑。


I have a class which is defined in the following manner. The interface and concrete type both have a Type Parameter which I expect to be a double, int, decimal or DateTime. I've added a where constraint of IComparable however this class does some heavy numeric lifting so I want to avoid boxing and unboxing. The class definitions are as follows:

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);         
        }     
    } 
} 

These classes would be declared and used in calling code something like as follows

var numeric = new NumericClass<int, double>();
numeric.DoLongNumericComputation(); 

Now internally the way I handle the multiple types is to cast T to double. However I am concerned that since I have specified that T is a type param of type IComparable that unboxing/boxing is going on. In addition DateTime provides an additional overhead. What I am doing in the case of this type is converting the .Ticks property to a double and operating on that.

I welcome any information on what is going on under the hood in the CLR, plus suggestions to improve performance such as API changes to strongly type each of the numeric operations to improve performance and memory usage.

Edit: I should also add the above implementation is sub-optimum as if you declare NumericClass it starts throwing on the cast from Tx to double. I can only assume its casting through IComparable although Im not sure.

解决方案

Without seeing a more complete example, here is what I can recommend.

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);
        }
    }
}

Now you don't need to cast your generic objects or have type specific logic in NumericClass.

这篇关于凡双重Typeparam的通用类型的限制 - 拳击/拆箱?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆