我在做什么错了......我的每个循环都很慢

时间:2017-03-23 20:18:57

标签: c#

我正在尝试连接两个文件中的字符串并将其保存在第三个文件中。但是当前两个文件中的记录更多(比如100000+条记录)时,我的输出文件需要很长时间才能生成。我在这里做错了什么......有人可以帮忙吗

 var fileA = File.ReadAllLines("File1.txt");
 var fileB = File.ReadAllLines("File2.txt"); 

然后在NxM文件中执行行中的笛卡儿,其中N和M代表 File1和File2中的行数。因此,如果每个都有100个和50个记录 文件1和文件2分别是输出为100 * 50 = 5000

        FileStream fs = new FileStream("OutputFile.txt", FileMode.Create);
        // First, save the standard output.
        TextWriter tmp = Console.Out;
        StreamWriter sw = new StreamWriter(fs);


        foreach (var lst in cartesian)
        {
            Console.WriteLine(lst);
            Console.SetOut(sw);
            Console.WriteLine(lst);
            Console.SetOut(tmp);
            Console.WriteLine(lst);
        }

        sw.Close();

2 个答案:

答案 0 :(得分:7)

我认为你做错了什么。合法地花费很长时间来进行100,000 x 100,000记录的笛卡尔连接。通过使用嵌套的for循环而不是LINQ进行连接,可以稍微提高性能,但是您的进程可能受I / O限制。

请注意,您无需使用Console.SetOut,可以直接在WriteLine上致电sw

foreach (var lst in cartesian)
{
  Console.WriteLine(lst);
  sw.WriteLine(lst);
  // and if you want to do it again: Console.WriteLine(lst);
}

答案 1 :(得分:0)

写入stdout时,

Console.WriteLine()相对较重。看到这个测试,我首先输出100000行到一个没有其他处理的文本文件,然后第二次测试我写入stdout两次并在每次迭代时调用SetOut。这与您的测试写入stdout两次略有不同,但每次迭代调用SetOut两次而不是一次。

FileStream fs = new FileStream(@"c:\temp\OutputFile.txt", FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
TextWriter tmp = Console.Out; // stdout since it hasn't been changed
Console.SetOut(sw); // point to file
var stopw = Stopwatch.StartNew();
for (int i = 0; i < 100000; i++)
{               
    Console.WriteLine(i); // writes to file
}
sw.Dispose();
fs.Dispose();
var toFileTotalMs = stopw.Elapsed.TotalMilliseconds;

// Reset console to write to stdout
Console.SetOut(tmp);
stopw.Restart();
for (int i = 0; i < 100000; i++)
{
    Console.WriteLine(i); // writes to stdout
    Console.SetOut(tmp); // point to stdout (every iteration)
    Console.WriteLine(i); // writes to stdout
}
var toConsoleTotalMs = stopw.Elapsed.TotalMilliseconds;

Console.WriteLine($"toFileTotalMs={toFileTotalMs}; toConsoleTotalMs={toConsoleTotalMs};");

Console.Read(); // leaves console window open

输出:

  

toFileTotalMs = 17.7198   toConsoleTotalMs = 15964.9133

因此,对stdout和Console.WriteLine()执行两次SetOut所花费的时间要比仅写入文件需要花费900倍。我只是尝试更改原始的for循环,除了写入文件之外每次迭代调用SetOut,它从17.7ms变为43.8ms。