为什么检查Console.OutputEncoding需要这么长时间?

时间:2017-08-04 18:09:10

标签: c# .net optimization

我正在对我的应用程序运行一些性能分析,并发现检查控制台输出编码所花费的时间几乎是我的应用程序运行完整性能迭代的时间的两倍。

我正在检查:

Console.OutputEncoding.EncodingName != Encoding.UTF8.EncodingName

这项检查需要大约80个滴答(8,000 ns),我的整个应用程序(生成控制台表)只需要大约50个滴答(5,000 ns)即可运行,并且可以运行数百个条件。

为什么检查输出编码会花费这么多时间?我可以加快速度吗?

2 个答案:

答案 0 :(得分:2)

OutputEncoding的吸气剂参考源:https://referencesource.microsoft.com/#mscorlib/system/console.cs,594

public static Encoding OutputEncoding {
    [System.Security.SecuritySafeCritical]  // auto-generated
    get {

        Contract.Ensures(Contract.Result<Encoding>() != null);

        if (null != _outputEncoding)
            return _outputEncoding;

        lock(InternalSyncObject) {

            if (null != _outputEncoding)
                return _outputEncoding;

            uint cp = Win32Native.GetConsoleOutputCP();
            _outputEncoding = Encoding.GetEncoding((int) cp);
            return _outputEncoding;
        }
    }
    ...

我注意到的第一件事是它已经锁定了,所以已经有一些开销。它似乎也懒得实例化:第一次得到OutputEncoding时,它需要做一个PInvoke后跟Encoding.GetEncoding(如果你看,这不是一个简单的任务)。但是所有后续调用都会避免锁定并返回已经实例化的值。因此,如果您多次获得该费用,则无论如何费用将分摊到几乎为零。

如果你只获得一次......你真的需要优化只需要8微秒的东西吗?

答案 1 :(得分:1)

如果我不得不冒险猜测它,因为你正在比较EncodingName,这会导致潜在的昂贵查询(以及随后的字符串比较)。您是否有理由不直接比较编码?

!Console.OutputEncoding.Equals( Encoding.UTF8 )

在本地测试它似乎要快得多。