What is the fastest way to check type?

Instead of overloading the function 100 times or creating 100 different Comparers for different types, I decided to check the type inside the same function.

For example, I use the default mapping to compare the values ​​of a set of types (primitives and strings) within 2 objects. It contains the following code:

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": ... 

Here I use the switch , which is said to be faster than the chain of if / else . But a.GetType().Name returns a string dynamically received, and this method enables string comparison. It doesn’t sound very fast. I need Comparer as fast as technically possible, because it will be used for large data collections.

Q: Is there a faster way to check the type of an object (which does not include string comparisons)? What is the fastest way?

+6
source share
2 answers

Okay, this is in your hand. Use 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; } 

it supports all primitives. for custom objects Write else if statements inside TypeCode.Object .

Hope this helps.

+6
source

From the comments, it sounds like you have a bunch of structured data, with subobjects of various types.

If the collections are large, the fastest way would be to use a dynamic codegen (possibly with expression trees) to create a single method that pulls out all the fields / properties of interest in a strongly typed way and performs strongly typed comparisons.

Basically, you use reflection to dynamically retrieve field / property types from a collection item type. Then you create MemberAccessExpression expressions, pass them to Expression.Equal , and all the results to Expression.AndAlso . Compiling the expression gives you a delegate that accepts two objects of a certain type contained in the collection.

The launch time will be a couple of orders slower than the code that you indicated in your question, but the cost per object will be much lower. You will need to check where the breakeven point is, but probably at low thousands.

+3
source

Source: https://habr.com/ru/post/949935/


All Articles