Mar*_*dik 13 .net c# console input stream
我需要从控制台的标准输入流快速读取数据.输入包含100.000行,每行20个字符(200万个字符); 用户从剪贴板粘贴它.我的程序工作约3分钟(非常慢;目标是10秒).它看起来像:
var inputData = new string[100000]; // 100.000 rows with 20 chars
for (int i = 0; i < 100000; i++) // Cycle duration is about 3 minutes...
{
inputData[i] = Console.ReadLine();
}
// some processing...
Run Code Online (Sandbox Code Playgroud)
我尝试了什么:
直接:Console.Read,Console.ReadKey - 相同的结果
Console.In:Read(),ReadLine(),ReadAsync(),ReadLineAsync(),ReadBlock(具有各种块大小),ReadBlockAsync(),ReadToEnd(),ReadToEndAsync()- 相同的结果
新的StreamReader(Console.OpenStandardInput(缓冲区))具有各种缓冲区和块大小- 相同的结果
在读取开始时隐藏控制台窗口,并在读取完成时显示- 加速10%
我尝试从文件中获取输入数据 - 它的工作完美而快速.但我需要从__ConsoleStream中读取.
我注意到,当输入读取正在进行时 - 进程conhost.exe主动使用处理器.
如何加快输入读数?
UPD:
增加/减少Console.BufferHeight和Console.BufferWidth无效
ReadFile msdn也慢慢来.但我注意到一个有趣的事实:
ReadFile(handle, buffer, bufferSize, out bytesCount, null);
// bufferSize may be very big, but buffer obtains no more than one row (with \r\n).
// So, it seems that data passed into InputStream row-by-row syncroniously.
Run Code Online (Sandbox Code Playgroud)在您的场景中,尝试显示插入符号会浪费大量时间。您可以禁用在 Windows 中显示的插入符号(我不知道如何在其他平台上执行此操作)。
不幸的是,.NET 没有公开必要的 API(至少在 4.6.1 中)。所以你需要以下本机方法/常量:
internal class NativeMethods
{
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool SetConsoleMode(IntPtr hConsoleHandle, int mode);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool GetConsoleMode(IntPtr hConsoleHandle, out int mode);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr GetStdHandle(int nStdHandle);
internal const int STD_INPUT_HANDLE = -10;
internal const int ENABLE_ECHO_INPUT = 0x0004;
}
Run Code Online (Sandbox Code Playgroud)
并在从剪贴板接收数据之前按以下方式使用它们:
var handle = NativeMethods.GetStdHandle(NativeMethods.STD_INPUT_HANDLE);
int mode;
NativeMethods.GetConsoleMode(handle, out mode);
mode &= ~NativeMethods.ENABLE_ECHO_INPUT; // disable flag
NativeMethods.SetConsoleMode(handle, mode);
Run Code Online (Sandbox Code Playgroud)
当您完成接收剪贴板数据后,不要忘记恢复控制台模式标志。我希望它能减少您的性能问题。有关控制台模式的更多信息可以在GetConsoleMode上找到
进一步的优化尝试可以包括: