gpt4 book ai didi

java - 添加 ArrayList 耗时过长(超过 50000 个节点)

转载 作者:行者123 更新时间:2023-11-29 06:06:18 26 4
gpt4 key购买 nike

我有一个问题。我想创建一个基于 IR 系统的搜索引擎。所以,我有一些文件,我获取我需要的信息并将它们存储在 HashMaps、TreeMaps、ArrayLists 等结构中。然后,我想将这些信息写入文件。所以,我同时打开了 2 个 FileWriters。但是我在其中添加了越来越多的字符串。

但是这个过程耗时太长。我不知道为什么。当我将所有内容放入 FileWriter 时,我通过 close() 关闭它。

您是否认为问题出在每次我在缓冲区中添加新字符串时的重新分配?

我是否应该遵循另一种策略打开缓冲区,写入,关闭它,然后在下一次再次打开以在先前数据的末尾写入?这会花费更少的时间吗?

P.S.:对于一个小的输入文件,代码完全符合我的要求。问题是当我使用大量的输入文件时。

public static void writeWordsandDfInFile(Map<String, Word> tmpMap) throws IOException
{
Set tmpSet = tmpMap.entrySet();//Transform to Set for quick iteration and printing
Iterator tmpIt = tmpSet.iterator();
String le3h=null;
int bytesPostingFile;
int bytesVocabularyFile;
String str_out = null;
String prev_str_out = null;
String str_out2 = null;
String str_tmp;
String str_tmp2;
String Tstrt;
int prevctr=0;
int flag=0;
int i=0;
int j;
int k;
int flag2;
int flag3;
int docId;
//////////////////
int SIZEDocumentsFileBytes;
int prevInDocumentsFileBytes = 0;
int newInDocumentsFileBytes = 0;
int prwth_kataxwrhsh;
int ctrPostingFileBytes=0;
int prwthMonofora=0;



giveWrdTakeBytePos=new HashMap<String,Integer>();//8a t dinw thn le3h kai 8a mou epistrefei thn 8esh se bytes mesa sto VocabularyFile.txt

// Create file
FileWriter fstream = new FileWriter(vocabularyFile.getPath());
BufferedWriter out = new BufferedWriter(fstream);
out.
out.write("Le3h Df PosInPostingFile.txt\n\n");
str_tmp=("Le3h Df PosInPostingFile.txt\n\n");

// Create file
FileWriter fstream2 = new FileWriter(postingFile.getPath());
BufferedWriter out2 = new BufferedWriter(fstream2);
out2.write("DocId Tf LineInFile PosInDocumentsFile\n\n");
str_tmp2=("DocId Tf LineInFile PosInDocumentsFile\n\n");



PostingFileBytes=new ArrayList<Integer>();//krataw ta bytes gia kaue eggrafh sto PostingFile



flag=0;
i=0;
while(tmpIt.hasNext())
{

Map.Entry m = (Map.Entry) tmpIt.next();
le3h=(String)m.getKey();

Set s = tmpMap.get(le3h).getDocList().entrySet();
Iterator it = s.iterator();
Map.Entry mm =(Map.Entry)it.next();
docId=(Integer)mm.getKey();


Set ss=tmpMap.get(le3h).getDocList().keySet();

Set stf=tmpMap.get(le3h).getTf().keySet();

Iterator ssIt = ss.iterator();




flag2=0;
prwth_kataxwrhsh=0;
while(ssIt.hasNext())
{
docId=(Integer)ssIt.next();

out2.write(docId+" "+tmpMap.get(le3h).getTf(docId));//grafw sto VocabularyFile.txt thn ka8e le3h kai to Df ths
if(flag2==0)
{
str_out2=(docId+" "+tmpMap.get(le3h).getTf(docId));
flag2=1;
}
else
{
str_out2=(docId+" "+tmpMap.get(le3h).getTf(docId));
}



flag3=0;
Tstrt=null;
for(k=0;k<tmpMap.get(le3h).ByteList.get(docId).size();k++)
{
out2.write(" "+tmpMap.get(le3h).ByteList.get(docId).get(k));

if(flag3==0)
{
Tstrt=(" "+tmpMap.get(le3h).ByteList.get(docId).get(k));
flag3=1;
}
else
{
Tstrt=Tstrt+(" "+tmpMap.get(le3h).ByteList.get(docId).get(k));
}

}
str_out2=str_out2+Tstrt;
out2.write(" ->"+DocumentsFileBytes.get(docId)+"\n");
str_out2=str_out2+(" ->"+DocumentsFileBytes.get(docId)+"\n");
bytesPostingFile=str_out2.toString().length();

////////////////////////////////////////////////////////////////////////////////////////////////



//................................................................................................................................
SIZEDocumentsFileBytes=PostingFileBytes.size();

if(prwthMonofora==0)
{
prevInDocumentsFileBytes=str_tmp2.toString().length();

prwthMonofora=1;

PostingFileBytes.add(prevInDocumentsFileBytes);
ctrPostingFileBytes=0;//dld. parxei kataxwrish sthn 8esh 0 tou posting file
newInDocumentsFileBytes=prevInDocumentsFileBytes + bytesPostingFile;
//System.out.println("EPOMENH: "+newInDocumentsFileBytes);
}
else
{
if(prwth_kataxwrhsh==0)//gia ka8e le3h mono thn prwth fora kai as exei DF>1
{
//System.out.println("Prohg. Timh:"+prevInDocumentsFileBytes);
prevInDocumentsFileBytes=newInDocumentsFileBytes;//apo prin
//System.out.println("BAZW: "+prevInDocumentsFileBytes);
PostingFileBytes.add(prevInDocumentsFileBytes);
ctrPostingFileBytes++;
prwth_kataxwrhsh=1;
}
else
{
prevInDocumentsFileBytes=newInDocumentsFileBytes;
}
newInDocumentsFileBytes=prevInDocumentsFileBytes + bytesPostingFile;
//System.out.println("EPOMENH: "+newInDocumentsFileBytes);
}


}


//------------------------------------------------------------------------------------------------------------------


int ptr=ctrPostingFileBytes;

out.write(le3h+" "+tmpMap.get(le3h).getDf());//grafw sto VocabularyFile.txt thn ka8e le3h kai to Df ths

out.write(" ->"+PostingFileBytes.get(ptr)+"\n");


if(flag==0)//thn prwth fora
{
str_out=(le3h+" "+tmpMap.get(le3h).getDf()+" ->"+PostingFileBytes.get(ptr)+"\n");
giveWrdTakeBytePos.put(le3h, str_tmp.toString().length());
flag=1;
prev_str_out=str_tmp+str_out;
}
else
{
giveWrdTakeBytePos.put(le3h, prev_str_out.toString().length());

str_out=str_out+(le3h+" "+tmpMap.get(le3h).getDf()+" ->"+PostingFileBytes.get(ptr)+"\n");
prev_str_out=prev_str_out+(le3h+" "+tmpMap.get(le3h).getDf()+" ->"+PostingFileBytes.get(ptr)+"\n");
}

//................................................................................................................................


}

//Close the output stream
out.close();

//Close the output stream
out2.close();

}

最佳答案

据我所知,您从不追加到文件中,而是始终写入新文件。但是从你上面写的(没有阅读整个代码)你想要将数据附加到文件。

new FileWriter("path", true);

这对你有帮助吗?

另一个建议删除文件写入并使用它:

public static void foo()
{
// ...

byte[] fifeMBByteAryOne = new byte[5242880];
ByteArrayStream bStream = new ByteArrayStream(fifeMBByteAryOne);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(bStream));
byte[] fifeMBByteAryTwo = new byte[5242880];
ByteArrayStream bStream2 = new ByteArrayStream(fifeMBByteAryTwo);
BufferedWriter out2 = new BufferedWriter(new OutputStreamWriter(bStream2));

// ...

}

private static class ByteArrayStream extends OutputStream {
int index = 0;
byte[] container;

public ByteArrayStream(byte[] container) {
this.container = container;
}

@Override
public void write(int b) throws IOException {
container[index++] = (byte)b;
}

}

然后让它再次运行,看看需要多长时间。如果它和以前一样慢,则文件不是您的问题。


通读代码后,我相当确定您是 Java 编程的学生或初学者,这很好,但您应该在问题中说明这一点。它还会导致人们给你建议,而不是直接解决你的问题。

您可以改进很多事情。首先,从我的角度来看非常重要:您的编码风格需要改进。真的吗!有关于如何编写变量(以小写字母开头)方法等的标准。使用它们。您使用的变量比您需要的多得多,并且您在方法的开头定义了它们。在不需要时使用 Sets 和 Iterators(例如

Set s = currentWord.getDocList().entrySet();
Iterator it = s.iterator();
Map.Entry mm = (Map.Entry) it.next();
docId = (Integer) mm.getKey();

那么你永远不会使用 docId 的值,但是这里的这个 Action 当然需要时间。

重写该方法,这次了解您所做的事情,只做您需要的事情,当您需要它时,就像现在这样,我不允许我公司的任何人为客户使用它。

第二:当你将代码发布到互联网时,一定要发布直接编译的代码。我需要 15 分钟来编译该代码。周围很少有人有那么大的耐心。

第三:对于您编写的文本少于 2MB 的情况,使用 StringBuilder 构建整个文本并最终将其写成一个东西通常很有用。这使得调试更容易。

第四:在你把代码发到网上之前一定要自己想过问题并测试过解决问题。在这种情况下,您可以使用 Dates 来执行此操作,只需编写如下文本:

// at the beginning of a loop
long startedAt = new Date().getTime();
// somewhen within the loop:
System.out.println("in situation X " + (new Date().getTime()-startedAt);

这样您就可以看到哪个步骤需要多长时间,然后可以开始优化该区域。

第五:如果在第四之后仍然存在问题,请务必发布一小段代码,清楚地说明您的问题。不要依赖其他用户来理解您的问题,而是向他们展示。通过使用您所要求的语言的 self 解释变量、方法和类名,让他们更容易。您的评论也是如此。

第六:你应该做这一切的原因是让你有能力自己解决你的问题,并且只向具有扩展技能的人询问值得他们花时间的问题。

祝你好运

关于java - 添加 ArrayList<Integer> 耗时过长(超过 50000 个节点),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8436840/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com