即使控制台不可见,Console.WriteLine 是否也会导致性能损失? (C#)

问题描述 投票:0回答:3

我有一个带有很多

WriteLine()
功能的控制台应用程序,这个应用程序也应该作为“服务”运行(计划任务,运行时用户未登录)。

在这种情况下,没有实际的 cmd 窗口可显示。在这种情况下,

Console.WriteLine()
仍然会导致明显的性能损失吗?

c# .net console-application
3个回答
5
投票

是的即使控制台不可见也会导致性能损失

我的实验是在控制台可见的情况下运行这段代码,然后在控制台隐藏的情况下再次运行并测量性能

首次运行控制台可见24683毫秒
第二次运行控制台可见23363毫秒

首次运行控制台隐藏167毫秒
第二次运行控制台隐藏162毫秒

    static void Main(string[] args)
    {
        WriteMilionLines();
    }

    static void WriteMilionLines()
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();

        for (int i = 0; i < 1000000; i++)
        {
           Console.WriteLine(i);
        }
        sw.Stop();

        string message = "ElapsedMilliseconds" + sw.ElapsedMilliseconds;
        File.WriteAllText(@"c:\log.txt", message);
    }

通过注释

Console.WriteLine(i);
行,将需要零毫秒


3
投票

不,不会被注意到。除非您的应用程序完成了 99%

Console.WriteLine()
并且几乎没有执行任何其他操作,否则差异可以忽略不计。

如果您仍然担心性能,您可以将控制台调用包装到您可以控制的方法中,并测量应用程序经历的总时间,甚至引入一个开关(布尔变量)来控制其调用。


0
投票

虽然这是一个老话题,但我为任何重新审视这个问题的人提供这个答案。

答案是:Console.Writeline 总是有成本,但它是否重要,取决于您在 Console.Writeline 中作为参数的内容

这是因为无论您是否启用了 stdout,Writeline 函数都会被调用,并且会计算其中的参数。因此,当您启用或禁用标准输出时,唯一改变的是写入标准输出(cmd 或文件)的额外成本

为了理解问题,请运行以下示例:

using System;
using System.Diagnostics;
using System.IO;
                
public class Program
{
    public static void Main()
    {
        Stopwatch sw = new Stopwatch();
        Console.SetOut(TextWriter.Null);

        sw.Start();
        Console.WriteLine("1000000");
        sw.Stop();
        Console.SetOut(Console.Error);
        Console.WriteLine("Elapsed Milliseconds (1): " + 
            sw.ElapsedMilliseconds);
        
        Console.SetOut(TextWriter.Null);
        
        sw.Restart();
        Console.WriteLine(CountToBillion());
        sw.Stop();
        Console.SetOut(Console.Error);
        Console.WriteLine("Elapsed Milliseconds (2): " + 
            sw.ElapsedMilliseconds);
    }


    static string CountToBillion()
    {
        var s = 0;        

        for (int i = 0; i < 1000000000; i++)
        {
           s=i;
        }
        return s.ToString();
    }
}

您可以看到,在 stdout 上写入一个简单的字符串需要 0 毫秒(或者可能是 1 毫秒,具体取决于您的硬件),而写入像上面这样的耗时函数的结果则需要 1500-2000 毫秒,即使 stdout 已禁用。

如果您从数据库访问数据,将它们作为 IEnumerable 获取,并错误地在 Console.WriteLine 中调用 ToList(),并且认为如果禁用了 stdout,这不会影响您,则此成本变得更加显着。它不仅可能导致显着的延迟,而且还会导致通过延迟加载应用对数据的任何后续查询。

这就是为什么您应该始终考虑使用记录器而不是 console.writeline,在这种情况下,例如,如果应用程序未在调试模式下运行等,则对 Log.Debug 参数的评估将被完全忽略。

© www.soinside.com 2019 - 2024. All rights reserved.