在.Net中将信息与“类型”对象相关联的最有效的性能方式是什么?

时间:2010-04-30 19:16:08

标签: c# .net reflection

我想将自定义数据与Type相关联,并在运行时以极快的速度检索该数据。

这只是我的想象,是我完美的世界:

  

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

这会非常快......当然这不存在!如果它确实我不会问。呵呵;)

这是使用自定义属性的方式:

  

var myInfo = typeof(MyClass).GetCustomAttribute(“MyInformation”);

这很慢,因为它需要查找字符串“MyInformation”

这是一种使用词典的方式< Type,MyInformation>:

  

var myInfo = myInformationDictionary [typeof(MyClass)];

这也很慢,因为它仍然是'typeof(MyClass)'的查找。

我知道字典非常快,但这还不够......它没有调用方法那么快。它甚至不是相同的速度顺序。

我不是说我希望它和方法调用一样快。我想将信息与类型相关联,并尽快访问它。我在问是否有更好的方式,或事件是最好的方式。

任何想法??

谢谢!

修改

我在之前的所有片段中提到的typeof(MyClass)都是实际可变的......我不知道它是一个特定的MyClass类型,它可以是任何类型:

  

输入myType = typeFromSomewhere;

即。在这种情况下,MyClass只是说这个类是由我制作的,而且任何其他可能出现在这种情况下的类型也是由我制作的...所以它读取了

  

typeof(我自己的一个类,我不知道是谁,但它确实是我的

编辑:结论

与字典相关的一些效果结果:

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

接口呼叫:

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

虚拟电话:

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

我看到我的字典估计不足! =)

似乎Type of Type对任何东西都比虚拟方法调用慢3到4倍。

使用字符串字典不是这种情况。那些比虚拟方法调用慢10到12倍。

所以我告诉了我错了!

而且,不,我不是一个导弹!有人在评论中假设这个=)

谢谢大家。

8 个答案:

答案 0 :(得分:5)

这不仅仅是你的“完美世界”,它也是C#!您可以使用extension methods精确制作您的建议工作:

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

在静态TypeUtilities类等中,您将定义以下内容:

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

至于你如何实际返回关于类型的信息,可以用多种方式完成。一个简单的if-block,一个静态Dictionary,对给定类型的反射(使用属性/方法),甚至其他。最好的方法在很大程度上取决于上下文和您的特定使用场景。

答案 1 :(得分:5)

Dictionary<Type,Object>适合我。

答案 2 :(得分:4)

如果类型是静态可用的,那么请考虑使用类似

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

用于,

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

并且可以访问,

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

这是有效的,因为泛型类的静态变量对于不同的泛型参数是唯一的。

如果该类型不是静态可用,那么您应该使用问题中提到的Dictionary<Type, V>并由其他人推荐。

答案 3 :(得分:2)

在您的类型上声明静态属性或方法。

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

然后您可以按如下方式访问代码中的数据

var myInfo = YourType.GetMyInformation();

还是我错过了这一点?

答案 4 :(得分:2)

嗯,你怎么用Dictionary<string, MyInformation>字典:

如果您使用的是typeof方法,则根据定义,您知道它们正在寻找的类型。相反,您可以声明const string MY_CLASS_TYPE_NAME = "MyNamespace.MyClass"

这不是最漂亮的,但速度非常快,不会限制你的功能。

答案 5 :(得分:2)

为什么不使用GetCustomAttributes(typeof(MyInformationAttribute), false)

恕我直言,使用属性是表达这种信息的语义正确方式。只需确保使用密封属性类,因为这样可以提高运行时性能。

虽然,这并不困难,并且可能更倾向于延迟加载或以某种方式缓存属性实例。我通常在初始化应用程序时使用静态字段执行此操作。

答案 6 :(得分:0)

编写System.Type 的扩展方法,它将为您执行所有此类操作。

答案 7 :(得分:0)

正如其他人所说,你可能是微观优化的,但是既然我们都在接受它的精神,我也会这样做:)

.NET类型类可以归结为它的运行时类型句柄,如果你不需要反射,它可以比完整类型更有效...

在我刚刚运行的非常简单的测试中,字典或者你正在使用的任何东西比Dictionary快约20%。

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

可用于代替完整类型实例