簡體   English   中英

檢查類型的最快方法是什么?

[英]What is the fastest way to check a type?

我決定在一個函數中檢查類型,而不是將函數重載100次或為不同類型創建100個不同的比較器。

例如,我使用默認比較器來比較2個對象中的一組類型(基元和字符串)的值。 它包含以下代碼:

public class DefComparer : IComparer<object> {
    public int Compare(object a, object b) {
        .... // a = a.GetType().GetField(field).GetValue(a); - not important for the question but I'm just showing that a&b below are different references
        switch (a.GetType().Name) {
            case "Byte":
                if ((byte)a == (byte)b) return 0;
                else if ((byte)a > (byte)b) return 1;
                else return -1;
            case "UInt16":
                if ((ushort)a == (ushort)b) return 0;
                else if ((ushort)a > (ushort)b) return 1;
                else return -1;
            case "SByte":
                if ((sbyte)a == (sbyte)b) return 0;
                else if ((sbyte)a > (sbyte)b) return 1;
                else return -1;
            case "Int16":
                ...

在這里,我使用的是一個switch語句,據說比if / else語句鏈更快。 但是a.GetType().Name返回一個動態獲得的字符串,該方法涉及字符串比較。 這對我來說聽起來不是特別快。 我需要Comparer在技術上盡可能快,因為它將用於大量數據集合。

問:有沒有更快的方法來檢查對象的類型(不涉及字符串比較)? 什么是最快的方式?

好吧,你手里拿着它。 使用TypeCode

        int a = 10;
        Type t = a.GetType();

        switch (Type.GetTypeCode(t))
        {
            case TypeCode.Boolean:
                break;
            case TypeCode.Byte:
                break;
            case TypeCode.Char:
                break;
            case TypeCode.DBNull:
                break;
            case TypeCode.DateTime:
                break;
            case TypeCode.Decimal:
                break;
            case TypeCode.Double:
                break;
            case TypeCode.Empty:
                break;
            case TypeCode.Int16:
                break;
            case TypeCode.Int32:
                break;
            case TypeCode.Int64:
                break;
            case TypeCode.Object:
                break;
            case TypeCode.SByte:
                break;
            case TypeCode.Single:
                break;
            case TypeCode.String:
                break;
            case TypeCode.UInt16:
                break;
            case TypeCode.UInt32:
                break;
            case TypeCode.UInt64:
                break;
            default:
                break;
        }

這支持所有原語。 對於Custom對象在TypeCode.Object寫入else if語句。

我希望這有幫助。

從評論中,聽起來好像你有一堆結構化數據,各種類型的子對象。

如果集合很大,最快的方法是使用動態codegen(可能使用表達式樹)來創建一個方法,以強類型方式提取所有感興趣的字段/屬性,並執行強類型比較。

基本上,您使用反射從集合成員類型動態獲取字段/屬性類型。 然后構建MemberAccessExpression表達式,將它們傳遞給Expression.Equal ,並將所有結果傳遞給Expression.AndAlso 編譯表達式會為您提供一個委托,該委托接收集合中包含的特定類型的兩個對象。

啟動時間比您在問題中顯示的代碼慢幾個數量級,但每個對象的成本會低很多。 你必須進行測試才能看到盈虧平衡點的位置 - 但可能只有數千美元。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM