将大数据保存到文件的最快方法

时间:2010-11-04 23:04:06

标签: c# java c++ numerical-methods

我在Java,C#和C ++中进行了一些数值计算。其中一些保存了大量数据(到文本文件)。最快的方法是什么?

C ++ 即可。

ofstream file;
file.open(plik);
for(int i=0;i<251;i++){
    for(int j=0;j<81;j++)
        file<<(i-100)*0.01<<" "<<(j-40)*0.01<<" "<<U[i][j]<<endl;
    file<<endl;
}

我认为这是非常快的(我是对的吗?:))

爪哇

void SaveOutput(double[][] U, String fileName) throws IOException
{
    PrintWriter tx = new PrintWriter(new FileWriter(fileName));
    for(int i=0;i<251;i++)
    {
        for(int j=0;j<81;j++)
        {
            tx.println(String.format("%e %e %e ",(i - 100) * dz, (j - 40) * dz, U[i][j]));
        }
        tx.println();
    }
    tx.close();
}

C#示例类似。

这就是困扰我的事情。我为每一行做了一个String对象(很多垃圾)。在这个例子中它并不多,但有时我有10 000 000行。这引出了我的问题:

  1. c ++示例可以更快吗?
  2. 我应该使用StringBuilder for Java,也可能因为行数
  3. 而使用它
  4. 还有其他方法或图书馆吗?
  5. C#怎么样?
  6. 谢谢

8 个答案:

答案 0 :(得分:5)

描述它。运行代码,计时,看看需要多长时间。如果花费的时间是可以接受的,请使用它。如果没有,弄清楚哪个部分需要花费很长时间才能运行,并对其进行优化。

  • 做对。
  • 快点。

那个命令。 (有些人在这两个人之前添加“make it run / build”...)

那就是说,我之前实际上已经在这类事情上运行指标。缺点:你正在等待磁盘,而磁盘是非常缓慢的。如果您使用C或C ++或Java编写它们并不重要,它们都在等待硬盘。

这是我在C中的各种I / O方法所做的previous post。不完全是您正在寻找的,但可能提供信息。

答案 1 :(得分:4)

一个字:简介。

请注意,将std::endl插入缓冲(文件)流会导致其刷新,这可能会降低性能(从语言POV开始,这意味着缓冲区被“写出”,尽管这可能不一定表示物理磁盘访问)。要简单地打印换行符,请使用'\n' - 它永远不会更糟。

答案 2 :(得分:2)

首先,最重要的是:使用缓冲的作家!

这可能包括在某些语言中启用频道缓冲,或在其他语言中使用BufferedWriter (in Java)或等效语言。如果不这样做可能会导致性能低得多,因为输出流可能会“过冲” - 上面的示例代码违反了这一点(FileWriter对缓冲一无所知)!

在许多情况下,人们可以认为CPU和主内存访问“便宜”而IO“昂贵” - 在这样的微不足道的情况下,将改善对IO本身的访问(例如缓冲而不是[over] flushing)将导致在最切实的收益。现代虚拟机和JIT做得非常好,短期对象分配/解除分配可能是这里“忧虑”最少的。

答案 3 :(得分:1)

使用Java.nio类来创建通道。频道是java的新手,比旧流快得多。你也应该缓冲写入。我不记得默认情况下通道是否缓冲。我需要读一些告诉你的。

最后,你可以创建很多字符串。你马上扔掉它们。我怀疑它会让你写入磁盘变慢。磁盘IO比CPU慢得多。

这就是我的想法:

fileChannel = new FileOutputStream("test.txt").getChannel();
for(int i=0;i<251;i++) {
  for(int j=0;j<81;j++) {
    fileChannel.write(ByteBuffer.wrap((String.format("%e %e %e ",(i - 100) * dz, (j - 40) * dz, U[i][j]) + "\n").toBytes());
  }
fileChannel.close();

答案 4 :(得分:1)

首先请注意,根据细节的不同,这个I / O绑定程序将得到很大的改进(例如,如果您使用C ++流或printf)。

对于C / C ++部分,有人说使用ol'printf操作更快。 可能更快,但不是那个数量级,所以我不会打扰。

对于Java版本,我认为它已经相当优化。

无法告诉C#,我的医生不允许我:)

答案 5 :(得分:0)

我希望在C或C ++中使用fprintf会更快。

答案 6 :(得分:0)

的Lukas,

首先,我主要了解C#,所以这里的所有内容都与.NET有关。

根据您要处理的行数,我不会创建字符串或使用StringBuilder。 StringBuilder仅帮助从许多较小的段创建字符串。

我认为您最好的选择是使用文件系统对象的Stream版本。这样,你根本就不存储字符串,所以你的内存使用量应该相当小。

此外,如果你的内存非常缺乏,你可以随时创建一个非托管字符串和P / Invoke。

埃里克

答案 7 :(得分:0)

对于Java,您不必创建所有这些字符串。摆脱String.format并直接写入字节。

无情地使用nio和个人资料