如何迭代处理大型数据文件?

时间:2014-02-22 12:21:32

标签: java som large-data

我有一个空格分隔的数据文件,其中有450万个条目,格式如下

  

CO_1 A 0 0 0 0 1

     

CO_2 A 0 0 0 0 1

此数据文件用作Self-Organizing Map (SOM)算法的输入,该算法遍历此文件100(在我的情况下)。

我使用以下readFile函数将文件完全复制到临时字符串中,并将字符串传递给SOM算法。

public String readFile()
{
    String temp = "";

    try
    {
        FileReader file = new FileReader(FILE_LOCATION);
        BR = new BufferedReader(file);
        String strLine = null;

        while((strLine = BR.readLine()) != null)
        {
            temp += strLine + "\n";
        }
    }
    catch(Exception e)
    {

    }

    return temp;
}

我觉得上面的方法给内存带来了沉重的负担,并减慢了可能导致内存溢出的迭代。目前我正在一个具有30GB内存分配的集群中运行此代码,并且执行甚至没有完成一次迭代约36小时。

我无法部分读取文件(如行块),因为一旦初始块完成,SOM将不得不轮询数据,这可能会导致更复杂的情况。

任何想法如何改进这一点,以便我可以成功地迭代450万条目100次。

修改

使用上述方法仅将整个文件读入字符串一次。然后在整个100次迭代中使用字符串变量。但是,每次使用字符串标记符来处理文件中的每一行*迭代次数。

4 个答案:

答案 0 :(得分:2)

不要为此目的使用字符串连接 为此目的,请使用String类而不是StringBuffer 考虑以下示例:

public StringBuffer readFile()
{
    StringBuffer tempSB = new StringBuffer();

    try
    {
        FileReader file = new FileReader(FILE_LOCATION);
        BR = new BufferedReader(file);
        String strLine = null;

        while((strLine = BR.readLine()) != null)
        {
            tempSB.append(strLine);
            tempSB.append("\n");
        }
    }
    catch(Exception e)
    {

    }

    return temp;
}  

这将节省你的堆内存。

答案 1 :(得分:2)

我想补充其他答案。尽管我认为你应该将数据存储在一个比字符串更有效的数据结构中,但我认为你编码的速度可能还有另一个原因。

由于您的文件大小似乎大约为100 MB,因此您的代码可能会变慢,因为Eclipse没有为其分配足够的堆空间。尝试添加以下标志:

-Xmx4G

这将为您的代码提供4 GB的堆空间。要做到这一点,在Eclipse中转到:

// Run -> Run Configurations -> <Select your main class on the left>
// -> <Select the 'Arguments' tab>
// -> <Add the string "-Xmx4G" to the 'VM arguments' text area>

这可能加快速度!

答案 2 :(得分:0)

使用String + =读取文件非常昂贵。我建议您将条目解析为数据结构,这应该需要大约1-10秒。重复迭代这应该不到一秒钟。每个条目使用150个字节的450万个条目应该使用大约0.5 GB,对于更复杂的结构可能使用1 GB。这应该不足以担心。

答案 3 :(得分:0)

如果您需要解析txt serial 文件并能够随机读取它,请使用持久存储,例如SQL数据库或{{ 1}}一个甚至是no-SQL。 这将为您带来以下好处:

  • 您不必将整个文件加载到RAM中
  • 您可以使用流处理 - &gt;逐行读取文件并仅保留RAM中的实际行
  • 解析和保存源文件会花费更多时间,但随机访问会更快。
  • 您甚至可以独立地在多个线程中解析和读取数据