Update:正如我预料的那样,社区针对这个问题给出的合理建议是“衡量一下然后看看”。chibacity 发布了 答案 https://stackoverflow.com/questions/4864974/using-threadstatic-to-replace-expensive-locals-good-idea/4865914#4865914一些非常好的测试为我做到了这一点;与此同时,我自己写了一个测试;我看到的性能差异实际上是如此巨大我觉得有必要写一篇关于它的博客文章。 http://philosopherdeveloper.com/posts/replacing-expensive-locals-with-threadstatic-fields.html
不过,我也应该承认汉斯的解释 https://stackoverflow.com/questions/4864974/using-threadstatic-to-replace-expensive-locals-good-idea/4865784#4865784认为ThreadStatic
属性确实不是免费的,实际上依赖于 CLR 辅助方法来发挥其魔力。这使得它是否是适用于任何任意情况的适当优化并不明显。
对我来说好消息是,在my如此看来,似乎有了很大的进步。
我有一个方法(除其他外)为一些局部变量实例化一些中等大小的数组(~50 个元素)。
经过一些分析后,我发现这种方法是性能瓶颈。并不是说该方法需要花费很长的时间来调用;而是该方法需要很长的时间来调用。相反,它被简单地称为many次,非常快(一次会话数十万到数百万次,这将是几个小时)。因此,即使对其性能进行相对较小的改进也是值得的。
我突然想到,也许我可以使用标记的字段,而不是在每次调用时分配一个新数组[ThreadStatic]
;每当调用该方法时,它都会检查该字段是否在当前线程上初始化,如果没有,则对其进行初始化。从那时起,同一线程上的所有调用都将有一个数组准备就绪。
(该方法会初始化数组本身中的每个元素,因此数组中存在“陈旧”元素不应该成为问题。)
我的问题很简单:这看起来是个好主意吗?使用过程中是否存在陷阱ThreadStatic
我应该了解这种方式的属性(即,作为一种性能优化,以减轻为局部变量实例化新对象的成本)?是一个性能ThreadStatic
领域本身或许并不伟大;例如,是否有很多额外的“东西”在后台发生,有其自己的一套成本,以使此功能成为可能?
对我来说,甚至尝试优化像 50 元素数组这样便宜(?)的东西也是错误的,如果是这样,一定要让我知道,但是general问题仍然存在。