我有一个空格分隔的数据文件,其中有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次迭代中使用字符串变量。但是,每次使用字符串标记符来处理文件中的每一行*迭代次数。
答案 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
。
这将为您带来以下好处: