2017-08-04 83 views
2

雖然這樣做對我們的應用一些分析,我發現這個代碼:原始類型轉換,無需拳擊

public TOut GetValue<TIn, TOut>(Func<TIn> getter) 
{ 
    var value = getter(); 

    // Do some stuff with the value 

    return (TOut)Convert.ChangeType(value, typeof(TOut)); 
} 

TInTOut的是int,double或字符串。

由於使用int或double時的裝箱,這在分析會話中顯示爲堆分配的重要來源。輸入值Convert.ChangeType被裝箱,因爲該方法需要一個對象,並且出於同樣的原因返回值被裝箱。

我想優化此代碼,因爲此方法用於高吞吐量服務,這種分配是禁止的。理想情況下,我會將該方法改寫爲非通用方法,但API被各個團隊廣泛使用,重構此類規模需要數月時間。與此同時,我正試圖緩解這個問題,並找到一種方法來改善這種情況,而無需更改API合同。然而,我一直在這方面掙扎了一段時間,還沒有找到解決辦法。

你知道一個方法,甚至醜陋的,以處理int - > double和double - > int轉換沒有拳擊,給定的方法合同?請注意,我無法更改參數,但我可以添加通用約束(例如where TIn : IConvertible,但這對我沒有多大幫助)。

+3

換句話說,你想要通用的'ChangeType'?您可以使用[「switch/case」](http://referencesource.microsoft.com/#mscorlib/system/convert.cs,348)來查看您關心的所有類型,或者使用盒裝版本。 – Sinatr

+0

也許看看[.NET參考資源的Convert.ChangeType](http://referencesource.microsoft.com/#mscorlib/system/convert.cs,dc591cb7008278c6)將有助於瞭解它的功能,也許可以讓你爲您的特定場景創建一個更短/更快/更高效的方法。 –

回答

1

如果您只需要專注一對夫婦的轉換,我認爲以下工作,並且不承擔任何每個呼叫分配:

private static int FromDouble(double other) 
    { 
     return (int)other; 
    } 
    private static double FromInt(int other) 
    { 
     return (double)other; 
    } 

    private static Func<double, int> di = FromDouble; 
    private static Func<int, double> id = FromInt; 
    public TOut GetValue<TIn, TOut>(Func<TIn> getter) 
    { 
     var value = getter(); 

     // Do some stuff with the value 

     if (typeof(TIn) == typeof(int) && typeof(TOut) == typeof(double)) 
     { 
      var gf = (Func<TIn, TOut>)(object)id; 
      return gf(value); 
     }else if (typeof(TIn) == typeof(double) && typeof(TOut) == typeof(int)) 
     { 
      var gf = (Func<TIn, TOut>)(object)di; 
      return gf(value); 
     } 

     return (TOut)Convert.ChangeType(value, typeof(TOut)); 
    } 

有一對夫婦進一步調整的可能這個進行, 當然。

+0

我沒有想到要代表一個代表,這很聰明。謝謝! –