c#中更快的控制台I/O方式
本文关键字:方式 控制台 | 更新日期: 2023-09-27 18:11:45
我最近开始在像sphere online judge这样的编程竞赛网站上使用c#。我注意到的一件事是,控制台I/O确实会减慢c#程序的速度。
我主要使用控制台。ReadLine和Console。WriteLine方法。对于整数解析,我编写了自己的解析器,因为内置的解析器相当慢
我知道,写入控制台是缓慢的,所以当有很多东西要写的时候,我使用StringBuilder来构建所有的输出,并使用一个单独的console . writeline (sb.ToString())调用一次写入所有的输出。
是否有更多的优化我可以加快I/O?除了我上面提到的,还有其他的I/O方式吗?
(请不要使用you-should-check your-algorithm-first之类的回答,这个问题是专门关于快速I/O的。)
我正在以这种方式加速控制台I/O:
解析长数组
static IEnumerable<T> ReadArray<T>(string arrayLine, Func<string, T> parseFunction, char separator = ' ')
{
int from = 0;
for (int i = 0; i < arrayLine.Length; i++)
{
if (arrayLine[i] == separator)
{
yield return parseFunction(arrayLine.Substring(from, i - from));
from = i + 1;
}
}
yield return parseFunction(arrayLine.Substring(from));
}
,你可以这样使用这个方法
var array = ReadArray(Console.ReadLine(), s => int.Parse(s)).ToArray();
您可以获得额外的毫秒避免ToArray()调用和直接返回数组,因为大多数时间数组长度是输入的一部分。
高效打印(有时还不够)
class Program
{
static StreamWriter output = new StreamWriter(Console.OpenStandardOutput());
internal static void Run()
{
int testCount = int.Parse(Console.ReadLine());
for (int t = 0; t < testCount; t++)
{
// Do your logic here. For example
var result = FooBarSolution(...);
output.WriteLine(result);
}
output.Flush();
}
}
GIST。
读取字符串并将其转换回整数或长等,有不必要的开销。
需要考虑的事情:
- 你能一次读取多个测试用例吗?
- 您能否以一种支持的格式读取输入,并且更容易转换为其他数据类型?[字符串对开发者来说很简单;)]
- 你能以缓冲的方式读取吗?
- 不安全代码是由SPOJ c#编译器支持吗?这样你就能救更多的虱子了?等等…
这是我对INOUT测试的看法
你应该使用一个巨大的缓冲区(byte[])并读取所有控制台输入字节-然后使用ReadByte()循环,直到你看到一个空白字符,并根据你的输入格式将该段转换为整数或长或字符串。
这是非常有效的,节省了很多时间严格限制的问题。
下面是我的示例代码
public int ReadInt()
{
byte readByte;
while ((readByte = GetByte()) < '-') ;
var neg = false;
if (readByte == '-')
{
neg = true;
readByte = GetByte();
}
var m = readByte - '0';
while (true)
{
readByte = GetByte();
if (readByte < '0') break;
m = m * 10 + (readByte - '0');
}
return neg ? -m : m;
}
这是我在SPOJ中使用的代码https://github.com/davidsekar/C-sharp-Programming-IO/blob/master/ConsoleInOut/InputOutput.cs
谢谢,
davidsekar