首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多调用StringComparer.CurrentCultureIgnoreCase效率在.NET中的应用

多调用StringComparer.CurrentCultureIgnoreCase效率在.NET中的应用
EN

Stack Overflow用户
提问于 2015-06-06 14:50:59
回答 2查看 1.2K关注 0票数 4

我一直在使用StringComparer.CurrentCultureIgnoreCase进行不区分大小写的比较和散列。但是,在检查了Reference之后,我看到它用每个调用创建了一个新实例(那么,它不是一个静态函数吗?为了形式的缘故)。无论如何,我的问题是,当您需要进行多个比较时,比如一个IEquality<T>实现,这样做是否有效:

代码语言:javascript
复制
// 2 instances per call
return StringComparer.CurrentCultureIgnoreCase.Equals(this.a, other.a)
  && StringComparer.CurrentCultureIgnoreCase.Equals(this.b, other.b) .. etc ..

或者也许:

代码语言:javascript
复制
public bool Equals(MyObj other)
{
  // 1 instance per call
  var equ = StringComparer.CurrentCultureIgnoreCase;
  return equ.Equals(this.a, other.a)
    && equ.Equals(this.b, other.b) .. etc ..
}

或者甚至缓存/池比较器,这样他们就不会每次调用Equals()时都创建arn?

代码语言:javascript
复制
// 1 instance per thread
[ThreadStatic]
private static StringComparer equ;

public bool Equals(MyObj other)
{
  if (equ == null) equ = StringComparer.CurrentCultureIgnoreCase;

  return equ.Equals(this.a, other.a)
    && equ.Equals(this.b, other.b) .. etc ..
}

对哪一个是最佳实践有什么感觉吗?

(感谢michael最初引用OrdinalIgnoreCase并不是一个新的例子,我转而使用了CurrentCultureIgnoreCase

EN

回答 2

Stack Overflow用户

发布于 2015-06-06 14:55:44

根据参考源,OrdinalIgnoreCase每次返回相同的静态实例:

代码语言:javascript
复制
public abstract class StringComparer : ...
{
    ...

    private static readonly StringComparer _ordinalIgnoreCase = new OrdinalComparer(true);        

    ...

    public static StringComparer OrdinalIgnoreCase { 
        get {
            Contract.Ensures(Contract.Result<StringComparer>() != null);
            return _ordinalIgnoreCase;
        }
    }

由于在实际的Contract.Ensures再分发表中省略了.NET调用,其余的字段访问几乎肯定会被抖动内联。

(同样适用于InvariantCulture、InvariantCultureIgnoreCase和Ordinal。)

另一方面,CurrentCulture和CurrentCultureIgnoreCase每次访问它们时都会返回新实例,因为当前的区域性可能在访问之间发生变化。在这种情况下,您应该缓存比较器吗?就我个人而言,我不会让我的代码变得更复杂,除非分析表明存在问题。

不过,在这种特殊情况下,我通常比较字符串是否相等,如下所示:

代码语言:javascript
复制
return String.Equals(this.a, other.a, StringComparison.OrdinalIgnoreCase);

现在,您根本不必担心StringComparer分配,即使您使用了CurrentCulture或CurrentCultureIgnoreCase,而且代码仍然很容易阅读。

票数 5
EN

Stack Overflow用户

发布于 2015-06-06 17:14:02

千万不要低估代码线程安全的成本。CurrentCulture是线程的一个属性,当然,不同的线程可以在不同的区域性中运行。您需要一个可以以线程安全的方式访问的缓存来存储对象。没有退休策略的缓存是内存泄漏,现在您还必须跟踪最近的使用情况,以及一种将有一段时间没有使用的对象退役的方法。没有一个是显而易见的。

只是在需要时创建对象要简单得多,而且成本更低。它很小,比一根绳子便宜。它不太可能持续很长时间。从第0代分配的内存没有得到提升,非常便宜。

.NET框架是高度微观优化的,他们没有搞错这个框架。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30684201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档