gpt4 book ai didi

c# - 逐字符写入控制台,最快的方法

转载 作者:太空狗 更新时间:2023-10-29 20:05:26 30 4
gpt4 key购买 nike

在我当前的一个项目中,我必须解析一个字符串,并将它的一部分写入控制台。在测试如何在没有太多开销的情况下执行此操作时,我发现我测试的一种方法实际上比 Console.WriteLine 更快,这让我有点困惑。

我知道这不是基准测试的正确方法,但我通常可以粗略地说“这比这快”,我可以在运行几次后判断次。

static void Main(string[] args)
{
var timer = new Stopwatch();

timer.Restart();
Test1("just a little test string.");
timer.Stop();
Console.WriteLine(timer.Elapsed);

timer.Restart();
Test2("just a little test string.");
timer.Stop();
Console.WriteLine(timer.Elapsed);

timer.Restart();
Test3("just a little test string.");
timer.Stop();
Console.WriteLine(timer.Elapsed);
}

static void Test1(string str)
{
Console.WriteLine(str);
}

static void Test2(string str)
{
foreach (var c in str)
Console.Write(c);
Console.Write('\n');
}

static void Test3(string str)
{
using (var stream = new StreamWriter(Console.OpenStandardOutput()))
{
foreach (var c in str)
stream.Write(c);
stream.Write('\n');
}
}

如您所见,Test1 正在使用 Console.WriteLine。我的第一个想法是简单地为每个字符调用 Write,请参见 Test2。但这导致花费了大约两倍的时间。我的猜测是每次写入后它都会刷新,这会使它变慢。所以我尝试了 Test3,使用 StreamWriter(AutoFlush 关闭),结果比 Test1 快了大约 25% ,我真的很好奇为什么会这样。还是写入控制台无法正确进行基准测试? (在添加更多测试用例时注意到一些奇怪的数据......)

谁能教教我?

此外,如果有更好的方法(通过一个字符串并只将它的一部分写入控制台),请随时发表评论。

最佳答案

首先,我同意其他评论,即您的测试工具还有待改进……我重写了它并将其包含在下面。重写帖子后的结果明显胜出:

//Test 1 = 00:00:03.7066514
//Test 2 = 00:00:24.6765818
//Test 3 = 00:00:00.8609692

由此看来,您是正确的,缓冲流写入器的速度提高了 25% 以上。它更快只是因为它有缓冲。 StreamWriter 实现在内部使用大约 1~4kb 的默认缓冲区大小(取决于流类型)。如果您使用 8 字节缓冲区(允许的最小缓冲区)构造 StreamWriter,您会发现大部分性能改进都消失了。您还可以通过在每次写入后使用 Flush() 调用来查看这一点。

下面是为获得上述数字而重写的测试:

    private static StreamWriter stdout = new StreamWriter(Console.OpenStandardOutput());
static void Main(string[] args)
{
Action<string>[] tests = new Action<string>[] { Test1, Test2, Test3 };
TimeSpan[] timming = new TimeSpan[tests.Length];

// Repeat the entire sequence of tests many times to accumulate the result
for (int i = 0; i < 100; i++)
{
for( int itest =0; itest < tests.Length; itest++)
{
string text = String.Format("just a little test string, test = {0}, iteration = {1}", itest, i);
Action<string> thisTest = tests[itest];

//Clear the console so that each test begins from the same state
Console.Clear();
var timer = Stopwatch.StartNew();
//Repeat the test many times, if this was not using the console
//I would use a much higher number, say 10,000
for (int j = 0; j < 100; j++)
thisTest(text);
timer.Stop();
//Accumulate the result, but ignore the first run
if (i != 0)
timming[itest] += timer.Elapsed;

//Depending on what you are benchmarking you may need to force GC here
}
}

//Now print the results we have collected
Console.Clear();
for (int itest = 0; itest < tests.Length; itest++)
Console.WriteLine("Test {0} = {1}", itest + 1, timming[itest]);
Console.ReadLine();
}

static void Test1(string str)
{
Console.WriteLine(str);
}

static void Test2(string str)
{
foreach (var c in str)
Console.Write(c);
Console.Write('\n');
}

static void Test3(string str)
{
foreach (var c in str)
stdout.Write(c);
stdout.Write('\n');
}

关于c# - 逐字符写入控制台,最快的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13370440/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com