日期:2014-05-18  浏览次数:21055 次

性能难题:PropertyInfo属性的读取为什么哪么慢???
性能难题:PropertyInfo属性的读取为什么哪么慢???

下面的程序调用ProcessProperties函数可以返回某个对象的属性与值字串,用来作为对象缓存的关键词,
但是发现这个读属性的过程速度难以接受。用单元测试竟然要15.625毫秒。晕。

究竟如何改进才能提高速度呢?头疼。。。。向各位高手求教了。。。。谢谢。。。。

  public class CacheKey
  {
private static Type typeCacheKeyAttr = typeof(CacheKeyAttribute);

  /// <summary>
  /// 处理属性
  /// </summary>
  /// <param name="baseObject"></param>
  /// <returns></returns>
  private static string ProcessProperties(object baseObject)
  {
  // 读取对象属性数组集合
  PropertyInfo[] properties = baseObject.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
  System.Collections.Generic.List<string> cachekeys = new System.Collections.Generic.List<string>();

  // 遍历属性数组
  foreach (PropertyInfo pi in properties)
  {
  cachekeys.Add(string.Format("{0}:{1}", KeyName(pi), pi.GetValue(baseObject, null)));
  }

  return string.Join("-", (string[])cachekeys.ToArray());
  }

  /// <summary>
  /// 关键词名称
  /// </summary>
  /// <param name="mi"></param>
  /// <returns></returns>
  private static string KeyName(MemberInfo mi)
  {
  if (mi.IsDefined(typeCacheKeyAttr, true))
  return ((CacheKeyAttribute)mi.GetCustomAttributes(typeCacheKeyAttr, true)[0]).KeyName;
  else
  return mi.Name;
  }
  }

  /// <summary>
  /// 缓存关键词特性类(特性类型都直接或间接地从 Attribute 类派生)
  /// 注:类引这里的特性类名时可以用全名,也可以前缀名称都可以正常工作;
  /// Indicates the property should be part of the cache key if set and other than the default value
  /// </summary>
  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
  public class CacheKeyAttribute : System.Attribute
  {
  /// <summary>
  /// String to use in place of the property or field name in the cache key creation
  /// </summary>
  /// <param name="keyName"></param>
  public CacheKeyAttribute(string keyName)
  {
  KeyName = keyName;
  Ignored = false;
  HasDefaultValue = false;
  }

  /// <summary>
  /// String to use in place of the property or field name in the cache key creation Only non default values will be included in the final key
  /// </summary>
  /// <param name="keyName"></param>
  /// <param name="defaultValue"></param>
  public CacheKeyAttribute(string keyName, object defaultValue)
  {
  KeyName = keyName;
  DefaultValue = defaultValue;
  HasDefaultValue = true;
  Ignored = false;
  }

  /// <summary>
  /// Always ingore this field or property in cache key generation if set to true (no need to set this to true if other constructors are used)
  /// </summary>
  /// <param name="includeInKey"></param>