如何在 C# 中创建写入同一文件的多个线程
How to create multiple threads that write to the same file in C#
我想将 10^5 行 10^5 个随机生成的数字写入一个文件,这样每一行
包含 10^5 个数字。因此我想知道最好的方法是什么
为了快速做到这一点。我想创建 10^5 个并发启动的线程
他们每个人写一行,以便在写入所需的时间内填充文件
只有 1 行。
public static void GenerateNumbers(string path)
{
using(StreamWriter sw = new StreamWriter(path))
{
for (int i = 0; i < 100000; i++)
{
for (int j = 0; j < 100000; j++)
{
Random rnd = new Random();
int number = rnd.Next(1, 101);
sw.Write(number + " ");
}
sw.Write('\n');
}
}
}
目前我是这样操作的,有没有更快的方法?
现在有了代码片段,可以应用一些优化。
static void Main(string[] args)
{
var sw = new Stopwatch();
const int pow = 5;
sw.Start();
GenerateNumbers("test.txt", pow);
sw.Stop();
Console.WriteLine($"Wrote 10^{pow} lines of 10^{pow} numbers in {sw.Elapsed}");
}
public static void GenerateNumbers(string path, int pow)
{
var rnd = new Random();
using var sw = new StreamWriter(path, false);
var max = Math.Pow(10, pow);
var sb = new StringBuilder();
for (long i = 0; i < max; i++)
{
for (long j = 0; j < max; j++)
{
sb.Append(rnd.Next(1, 101));
sb.Append(' ');
}
sw.WriteLine(sb.ToString());
sb.Clear();
if (i % 100 == 0)
Console.WriteLine((i / max).ToString("P"));
}
}
以上代码以相当不错的速度执行 IO 写入(请记住限制是 IO 速度,而不是 CPU / 数字生成)。另请注意,我 运行 从 VM 内部获取代码,因此我可能无法获得最佳 IO 结果。
- 正如 Neil Moss 在评论中提到的,您不需要在每个 运行.
上实例化 Random
class
- 我正在使用
StringBuilder
生成一行来写入 in-memory,然后将其写入磁盘。
- 因为这确实需要一些时间,所以我添加了一个进度跟踪器(这增加了极少的开销)。
- 一个 10^4 行的 10^4 数字文件的大小已经是 285MB,并且在 4.6767592 秒内生成。
- 像上面这样的 10^5 案例会产生一个 25.5 GB 的文件,需要 5:54.2580683 才能生成。
我还没有尝试过,但我想知道如果您更感兴趣的是将数据写入磁盘而不是将数据写入 ZIP 文件,您是否不能通过将数据写入 ZIP 文件来节省时间格式本身。压缩的数字 TXT 文件应该 fair-bit 更小,因此写入速度应该快得多。
我想将 10^5 行 10^5 个随机生成的数字写入一个文件,这样每一行 包含 10^5 个数字。因此我想知道最好的方法是什么 为了快速做到这一点。我想创建 10^5 个并发启动的线程 他们每个人写一行,以便在写入所需的时间内填充文件 只有 1 行。
public static void GenerateNumbers(string path)
{
using(StreamWriter sw = new StreamWriter(path))
{
for (int i = 0; i < 100000; i++)
{
for (int j = 0; j < 100000; j++)
{
Random rnd = new Random();
int number = rnd.Next(1, 101);
sw.Write(number + " ");
}
sw.Write('\n');
}
}
}
目前我是这样操作的,有没有更快的方法?
现在有了代码片段,可以应用一些优化。
static void Main(string[] args)
{
var sw = new Stopwatch();
const int pow = 5;
sw.Start();
GenerateNumbers("test.txt", pow);
sw.Stop();
Console.WriteLine($"Wrote 10^{pow} lines of 10^{pow} numbers in {sw.Elapsed}");
}
public static void GenerateNumbers(string path, int pow)
{
var rnd = new Random();
using var sw = new StreamWriter(path, false);
var max = Math.Pow(10, pow);
var sb = new StringBuilder();
for (long i = 0; i < max; i++)
{
for (long j = 0; j < max; j++)
{
sb.Append(rnd.Next(1, 101));
sb.Append(' ');
}
sw.WriteLine(sb.ToString());
sb.Clear();
if (i % 100 == 0)
Console.WriteLine((i / max).ToString("P"));
}
}
以上代码以相当不错的速度执行 IO 写入(请记住限制是 IO 速度,而不是 CPU / 数字生成)。另请注意,我 运行 从 VM 内部获取代码,因此我可能无法获得最佳 IO 结果。
- 正如 Neil Moss 在评论中提到的,您不需要在每个 运行. 上实例化
- 我正在使用
StringBuilder
生成一行来写入 in-memory,然后将其写入磁盘。 - 因为这确实需要一些时间,所以我添加了一个进度跟踪器(这增加了极少的开销)。
- 一个 10^4 行的 10^4 数字文件的大小已经是 285MB,并且在 4.6767592 秒内生成。
- 像上面这样的 10^5 案例会产生一个 25.5 GB 的文件,需要 5:54.2580683 才能生成。
Random
class
我还没有尝试过,但我想知道如果您更感兴趣的是将数据写入磁盘而不是将数据写入 ZIP 文件,您是否不能通过将数据写入 ZIP 文件来节省时间格式本身。压缩的数字 TXT 文件应该 fair-bit 更小,因此写入速度应该快得多。