开发者

What is the most efficient performance-wise way of associating information with a 'Type' object in .Net?

I want to associate custom data to a Type, and retrieve that data in run-time, blazingly fast.

This is just my imagination, of my perfect world:

var myInfo = typeof(MyClass).GetMyInformation();

this would be very fast... of course this does not exist! If it did I would not be asking. hehe ;)

This is the way using custom attributes:

var myInfo = typeof(MyClass).GetCustomAttribute("MyInformation");

this is slow because it requires a lookup of the string "MyInformation"

This is a way using a Dictionary<Type, MyInformation>:

var myInfo = myInformationDictionary[typeof(MyClass)];

This is also slow because it is still a lookup of 'typeof(MyClass)'.

I know that dictionary is very fast, but this is not enough...开发者_开发百科 it is not as fast as calling a method. It is not even the same order of speed.

I am not saying I want it to be as fast as a method call. I want to associate information with a type and access it as fast as possible. I am asking whether there is a better way, or event a best way of doing it.

Any ideas??

Thanks!

EDIT:

The typeof(MyClass) I mentioned in all of previous snippets, are actualy variable... I don't know that it is a specific MyClass type, it could be any type:

Type myType = typeFromSomewhere;

i.e. MyClass in this case just says that the class is made by me, and any other types that could come into this situation is also made by me... so it reads

typeof( One of My Own Classes, that I don't know witch one is it, but it is mine for sure )

EDIT: CONCLUSION

Some performance results related to dictionaries:

Dic.buckets | Dic.Count | Dic.Key | Ops(x17)/s | Avg.Time | Min.Time | Max.Time
-----------------------------------------------------------------------------
     17519  |    12467  |   Type  |    1051538 |  0.95μs  |  0.86μs  |  0.42ms
       919  |      912  |   Type  |     814862 |  1.23μs  |  1.14μs  |  0.46ms
   1162687  |      912  |   Type  |    1126382 |  0.89μs  |  0.81μs  |  0.33ms
       919  |      912  |   Type  |     806992 |  1.24μs  |  1.16μs  |  0.21ms
        17  |       17  |   Type  |     872485 |  1.15μs  |  1.06μs  |  0.31ms
-----------------------------------------------------------------------------
     36353  |    18160  |  String |     227520 |  4.40μs  |  3.98μs  |  0.47ms
       919  |      911  |  String |     219159 |  4.57μs  |  4.14μs  |  0.29ms
   1162687  |      911  |  String |     236384 |  4.23μs  |  3.82μs  |  0.41ms
       919  |      911  |  String |     223042 |  4.49μs  |  4.10μs  |  0.43ms
        17  |       17  |  String |     229985 |  4.35μs  |  3.94μs  |  0.28ms

Interface Call:

ops(x17)/s: 2896001
Average: 0.35μs
Min: 0.34μs
Max: 1.20μs

Virtual Call:

ops(x17)/s: 3115254
Average: 0.32μs
Min: 0.32μs
Max: 0.65μs

I see that I have under-estimated Dictionaries!!! =)

It seems that Dictionary of Type to anything is 3x to 4x slower than a virtual method call.

This is not the case using Dictionary of strings. That ones are 10x to 12x slower than a virtual method call.

So I have prooved me wrong!

And, NO I AM NOT MAKING A MISSILE!!! someone has supposed this in a comment bellow =)

Thanks everybody.


Dictionary<Type,Object> works for me.


It's not just your "perfect world", it's C# too! You can use extension methods to make precisely what you suggested work:

var myInfo = typeof(MyClass).GetMyInformation();

In a static TypeUtilities class or such, you would define the following:

public static InfoType GetMyInformation(this Type type)
{
    // Return InfoType object.
}

As to how you actually return the information on the type, that could be done in anumber of ways. A simple if-block, a static Dictionary, reflection on the given type (using attributes/methods), or even others. The best approach there depends very much on the context and your particular usage scenario.


If the type is statically available then consider using something like,

public class Data<T, V>
{
    public static V Info;
}

which is used like,

Data<int, string>.Info = "A string associated with int";
Data<string, string>.Info = "A string associated with string";

and is accessed like,

Console.WriteLine(Data<int, string>.Info);
Console.WriteLine(Data<string, string>.Info);

This works because static variables of a generic class are unique for distinct generic parameters.

If the type is not statically available then you should use Dictionary<Type, V> as mentioned in your question and recommended by others.


Declare static properties or methods on your type.

class YourType
{
  public static string GetMyInformation()
  {
    return "Some info on this type";
  }
}

Then you can access the data in your code as follows

var myInfo = YourType.GetMyInformation();

Or did I miss the point?


Um, how about you use a dictionary of Dictionary<string, MyInformation>:

You know they type you are looking for already by definition if you are using the typeof method. Instead, you could declare a const string MY_CLASS_TYPE_NAME = "MyNamespace.MyClass"

It's not the prettiest, but it's blazingly fast and doesn't limit your functionality.


Why not use GetCustomAttributes(typeof(MyInformationAttribute), false)?

IMHO, using attributes is the semantically correct way to express information like this. Just make sure you use a sealed attribute class, as that improves the runtime performance.

Though, it wouldn't be difficult, and would probably be preferable to either lazy-load or somehow otherwise cache the attribute instances. I generally do this once using a static field when the application is initialized.


write extension methods for System.Type that will do all such operations for you.


As other people have said, you are probably micro-optimizing, but since we are all getting into the spirit of it, I will too :)

The .NET type class can be boiled down to it's runtime type handle which can be more efficient than the full type if you don't need reflection...

Dictionary or whatever you are using is about 20% faster than Dictionary in the very simple test I just ran.

typeof(object).RuntimeTypeHandle;
// and
instance.GetType().RuntimeTypeHandle;

can be used in place of a full type instance

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜