C#标准输入/输出性能

4
我正在启动一个进程,并通过stdin将指令xml文件写入目标进程。虽然只有2k的数据,但传输这么多数据却需要近半秒钟的时间,这对我来说似乎太长了。我测量的是子进程消耗数据所需的时间。
你有什么加快速度的建议吗?
父进程:
    ProcessStartInfo psi = new ProcessStartInfo(path, args);
    psi.CreateNoWindow = true;
    psi.UseShellExecute = false;
    psi.RedirectStandardInput = true;
    Process p = Process.Start(psi);
    p.StandardInput.Write(stdin);
    p.StandardInput.Close();

子进程:

    Stream s = Console.OpenStandardInput();
    StreamReader sr = new StreamReader(s);
    return sr.ReadToEnd();

记录一下,我尝试过一种改变方法,先写出数据的长度,然后读取相同数量的字节,以避免等待流关闭,但这并没有对性能产生影响。
我正在生成许多小型工作进程,所以每个进程额外的0.5秒时间会让我疲惫不堪!
编辑:感谢所有评论,但我特别寻求任何改善标准输入性能的方法。我提到的0.5秒是在子进程代码周围测量得到的。
    Stopwatch sw = new Stopwatch();
    sw.Reset();
    sw.Start();
    string stdin = ReadStdIn();
    sw.Stop();
    Console.WriteLine("Elapsed time to read stdin: " + sw.ElapsedMilliseconds);
第二次编辑:在这种情况下,生成线程是不可能的。由于问题范围之外的原因,我需要每个工作都有自己的内存空间(限制为32位2GB)。

1
生成许多小的工作线程。 - Hans Passant
2个回答

1

你尝试过不读写数据,只做同样的事情吗?比如测量父程序启动子程序、准备运行、运行和退出所需的时间?

由于你的“子”代码看起来也是C#,可能是加载子exe +库、启动.Net运行时等开销导致花费了0.5秒,而不是读写数据。

话虽如此,在Windows上启动新进程并不便宜(至少不像大多数*nix变体那样)。如果你对这里的时间非常关注,可以考虑使用线程而不是进程。


感谢您的评论,但我是在子进程中测量(一旦它已经启动)。我正在测量从stdin读取数据所需的时间。 - Alan Jackson

0

可能是启动子进程花费了太长时间,而不是从stdin读取。请记住,每次都需要重新JIT CIL。

如果是这种情况,请考虑在您要生成的EXE上运行ngen install。这将通过基本上只JITting子EXE一次而不是每次运行它来显着提高其启动时间。


ngen会在启动时间上有所帮助,但进程启动和.NET启动时间可能仍然超出您的处理能力。 - Jonathan Rupp
@Jonathan:我建议让原帖作者尝试这个解决方案,并决定它是否足够快以满足他的目的 - Timwi
ngen 可能在一般情况下有所帮助,但对于我的特定情况,我正在测量子进程实际读取 stdin 的时间,而不是启动时间。 - Alan Jackson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接