检测不可变量的高效方法?

我有一个实用程序,旨在传递我们系统周围的对象。 由于它是一个multithreading环境,因此该实用程序会对其传递的每个对象进行深层复制,以防止出现任何线程安全问题。 我正在努力转换我们的系统以使用不可变对象来消除对此副本的需要。 我想知道检测对象是不可变的最好(最快)方法是什么?

我的第一个想法就是了解我们放在所有不可变对象(MessageAttribute)上的属性。 正如您从下面的性能配置文件中看到的那样,它会受到很大影响(大约是所有其他检查执行时间的10倍)。

在此处输入图像描述

我怎么能检测到我的不可变通过? 我可以做一个typeof()比较,看起来效果更好,但这看起来相当笨拙,而且随着我们一直添加更多不可变的东西,它将是难以维护的。

编辑:我忘了提到布尔值被重构为变量以用于分析,实际上,结果存储在isDefined的表达式实际上是在else if语句中,因此将被击中大约10倍。这个配置文件(我更关心平均执行时间而不是绝对执行时间)。

创建一个接口(例如, IImmutable )并在所有不可变类上使用它。

您只需要使用typeof()检查此接口以检测不可变的。

typeof()是一个编译时检查,因此您没有性能损失。

你只在else分支中使用isDefined ,它比then分支少10倍。 仅在需要时计算值。 这应该将其成本降低10倍。

除此之外,您可以为计算引入缓存。 您可能检查的类型可能很少,因此缓存很小。

我只是缓存结果,因为类型的属性不会改变。

 public class SomeHelperClass { private static readonly ConcurrentDictionary messageAttributesCache = new ConcurrentDictionary(); private static readonly Type messageAttributeType = typeof(MessageAttribute); public static bool IsMessageAttributeDefined(Type type) { bool isDefined = false; if (messageAttributesCache.TryGetValue(type, out isDefined)) { return isDefined; } isDefined = type.IsDefined(messageAttributeType, false); return messageAttributesCache[type] = isDefined; } } 

然后用

 bool isDefined = SomeHelperClass.IsMessageAttributeDefined(type); 

您可以使解决方案通用,我只是想一想这是一些快速丑陋的代码。 但这会更好。

我最终实现了一个在静态构造函数中初始化的Hash集,并获取了我想要传递的所有类型。

 private static HashSet m_PassableTypes; // static SynthesisExtensions() { // m_PassableTypes = new HashSet(); foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (Type type in assembly.GetTypes()) { if (type.IsValueType || type == typeof (string) || type.Module.Name == "FSharp.Core.dll" || type.IsDefined(typeof (MessageAttribute), false)) { m_PassableTypes.Add(type); } } } } 

这使我可以执行一个非常快速的HashSet查找,这样可以提高性能。

  Type type = instance.GetType(); if (m_PassableTypes.Contains(type)) { // cache the self-reference referenceCache.Add(instance, instance); // return the value itself return instance; } 

感谢您的帮助! 我欢迎任何有关此解决方案的想法