StreamReader 对于大文件来说非常慢

问题描述 投票:0回答:3

我想读入一个文件,在本例中为 3mb 这样做大约需要 50-60 秒,看起来很慢。有谁知道如何使其更快?

string text = null;
using (StreamReader sr = new StreamReader(file, Encoding.Default))
{
    string line;
    while ((line = sr.ReadLine()) != null)
    {
        text += (line);
        backgroundWorker1.ReportProgress(text.Length);
    }
}

我还需要使用后台工作人员,以便我可以报告已加载的百分比(对于 500mb 到 1gb 左右的文件)

c# streamreader
3个回答
7
投票

使用 StringBuilder 创建行 - 它比字符串连接性能更高。

using System.Text;

//...

StringBuilder text = new StringBuilder();
using (StreamReader sr = new StreamReader(file, Encoding.Default))
{
    string line;
    while ((line = sr.ReadLine()) != null)
    {
        text.Append(line);
        backgroundWorker1.ReportProgress(text.Length);
    }
}

// ...
// Do something with the file you have read in.
Console.WriteLine(text.ToString());

3
投票

StreamReader 对于大文件 C# 来说非常慢

不,不是。您花费的时间不是花费在流阅读器上。

text += (line);

这一行正在创建一个新字符串。为此必须分配新的内存。对于大文件来说,这会产生大量的垃圾。时间越长,您执行的复制操作就越多。 如果这就是你用它的目的

backgroundWorker1.ReportProgress(text.Length);

也没什么用。你还可以有一个新变量

int textLength = 0

然后你设置

textLength += line.Length

无需所有文本操作。

性能问题?

永远不要

假设,总是使用分析器。 一些背景数学,顺便说一句:

(适用于 500mb 到 1gb 左右的文件)

这意味着一旦加载 500mb 的数据,您的代码就会每行
进行 500mb(如果文件是 Unicode)到 1gb(字符串是 ascii 文件大小的两倍)的复制操作。

您可能想查看计算机的内存速度。根据服务器等,您可能会被限制为每秒 50GB(高端 X99 - 较新的 DDR 4 内存速度更快,但工作站通常通道少得多,因此速度又慢),并且副本计数双倍(读取和写入)。这意味着您真的开始遇到“复制字符串使内存总线超载”的情况。

您可以使用此行:

0
投票
string text = System.IO.File.ReadAllText(file);


© www.soinside.com 2019 - 2024. All rights reserved.