C# NLog 性能 Class 变量

C# NLog Performance Class Variable

使用 NLog 似乎大大降低了我访问 class 变量的速度。当我 运行 时,s1 的代码比 s2 慢 2 倍,这是预期的。但是当我取消注释 GetCurrentClassLogger 行时,s1 变得比 s2 慢大约 800 倍。我正在使用 .NET Core 2 和 NLog 4.5.3。这是预期的行为吗?是什么导致性能下降?感谢您提供的所有帮助!

class Program
{
    //private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
    private static readonly DateTime _epoch = new DateTime(1970, 1, 1);

    static void Main(string[] args)
    {
        DateTime epoch = new DateTime(1970, 1, 1);
        int count = 10000;
        Stopwatch s1 = new Stopwatch();
        Stopwatch s2 = new Stopwatch();

        s1.Start();
        for (int i = 0; i < count; i++)
        {
            var x = DateTime.UtcNow.Subtract(_epoch).TotalSeconds;
        }

        s1.Stop();

        s2.Start();
        for (int i = 0; i < count; i++)
        {
            var x = DateTime.UtcNow.Subtract(epoch).TotalSeconds;
        }

        s2.Stop();

        Console.WriteLine(s1.ElapsedTicks);
        Console.WriteLine(s2.ElapsedTicks);
        Console.ReadLine();
    }
}

当您第一次访问 class 上的字段时,系统需要初始化 class 上的所有静态字段 - 这次您的基准测试正在测量。注释掉第一行后,这只是将 _epoch 设置为新的 DateTime 实例。在第一行中,这也调用了 NLog 代码以初始化记录器。

当您访问 _epoch 时,您第一次访问 class 上的字段是在您的第一个循环中。这意味着它在 s1 之内,因此它也在测量 class 初始化时间。如果您这样修改代码:

class Program
{
    private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
    private static readonly DateTime _epoch = new DateTime(1970, 1, 1);

    static void Main(string[] args)
    {

        DateTime epoch = new DateTime(1970, 1, 1);
        int count = 10000;
        Stopwatch s1 = new Stopwatch();
        Stopwatch s2 = new Stopwatch();

        Stopwatch s3 = new Stopwatch();
        s3.Start();
        var e = _epoch;
        s3.Stop();

        s1.Start();
        for (int i = 0; i < count; i++)
        {
            var x = DateTime.UtcNow.Subtract(_epoch).TotalSeconds;
        }

        s1.Stop();

        s2.Start();
        for (int i = 0; i < count; i++)
        {
            var x = DateTime.UtcNow.Subtract(epoch).TotalSeconds;
        }

        s2.Stop();
        Console.WriteLine(s3.ElapsedTicks);
        Console.WriteLine(s1.ElapsedTicks);
        Console.WriteLine(s2.ElapsedTicks);
        Console.ReadLine();
    }
}

您可以看到大部分时间花在了 s3 内,因为 _epoch 在那里进行了访问,因此初始化那些静态成员。