1

我尝试测量使用 NIO(读取单个文件最慢)、BufferedInputStream 和逐行读取文件(每次通过平均 600 毫秒)然后使用 Filereader 和数组读取文件的几种方法的性能固定大小作为缓冲区(最快)

文件是 Windows .txt 文件格式的 95 MB 纯文本。将字符转换为字符串确实是瓶颈,但我注意到这种方法的内存消耗巨大。对于 95 MB 的 lorem ipsum,这会消耗多达 1 GB 的 RAM。我还没找到原因。

我尝试过的没有效果:

通过调用 System.gc() 发出垃圾收集器 在方法结束之前将所有指针变量设置为 null(但无论如何它们都应该是,它们仅在方法内定义)。

private void testCharStream() {
            File f = f = new File("c:/Downloads/test.txt");
    long oldTime = System.currentTimeMillis();
    char[] cbuf = new char[8192];
    StringBuilder builder = new StringBuilder();
    try {

        FileReader reader = new FileReader(f);

        while (reader.read(cbuf) != -1) {
            builder.append(cbuf);
        }

        reader.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    long currentTime = System.currentTimeMillis();

    System.out.println(currentTime - oldTime);
}
4

3 回答 3

2

试试 Apache Commons IO:http ://commons.apache.org/proper/commons-io/ 我没有对它进行基准测试,但我认为代码已经过优化。

于 2013-08-25T11:58:34.090 回答
0

我想出了不错的解决方案。使用 Apache Commons IO 包,内存峰值为777,1 MB,最低 220 MB 和 710 ms 平均需要 95 MB 文本文件变为红色。

我所做的是在方法结束时将带有指向 StringBuilder 对象的指针的变量设置为 null,并建议垃圾收集器实际完成它的工作 (System.gc())。内存峰值为540 MB,是之前达到的值的 1/2 以上!此外,通过将缓冲区大小更改为 1024 意味着每次通过 40 毫秒的改进,从 490 到 450 甚至更少。所以我的函数只需要63.4%的 Apache 时间来读取文件。这几乎减少了40%。有什么想法可以进一步提高性能吗?

这是功能。

private void testCharStream() {
    long oldTime = System.currentTimeMillis();
    char[] cbuf = new char[1024];
    StringBuilder builder = new StringBuilder();

    try {

        FileReader reader = new FileReader(f);

        while (reader.read(cbuf) != -1) {
            builder.append(cbuf);
        }

        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    long currentTime = System.currentTimeMillis();
    builder = null;
    System.gc();
    System.out.println(currentTime - oldTime);
}
于 2013-08-25T14:58:45.453 回答
0

为了获得更好的性能,您可以使用BufferedReader。此类允许您逐行读取文件。这种方法不会浪费时间逐字阅读文件,而是更快地执行任务。您可以在半秒内读取纯文本文件(大小:1 MB)。只需使用以下代码。

File f=new File("文件路径");
FileReader fr=new FileReader(f)
BufferedReader br=new BufferedReader(fr);

字符串行="";
StringBuilder builder=new StringBuilder();
尝试 {
while((line=br.readLine())!=null)
builder.append(line+"\n");
}
捕捉(异常 e)
{
e.printStackTrace();
}

您可以在使用System.currentTimeMillis().

于 2013-08-25T20:35:37.003 回答