使用 Buffered 提高读写大文件的速度 Write/Reader

Improve the speed of reading and writing big files with Buffered Write/Reader

我想读取文本文件并将每个单词转换为数字。然后为每个文件在新文件中写入数字序列而不是单词。我使用 HashMap 为每个单词分配一个数字(标识符),例如,单词 apple 被分配给数字 10 所以无论何时,我在按顺序编写 10 的文本文件中看到 apple。我只需要一个 HashMap 来防止为一个词分配多个标识符。我写了下面的代码,但它处理文件的速度很慢。例如,将大小为 165.7 MB 的文本文件转换为序列文件需要 20 个小时。我需要将 600 个相同大小的文本文件转换为序列文件。我想知道有什么方法可以提高我的代码效率。为每个文本文件调用以下函数。

public void ConvertTextToSequence(File file) {
    try{

        FileWriter filewriter=new FileWriter(path.keywordDocIdsSequence,true);
        BufferedWriter bufferedWriter= new BufferedWriter(filewriter);

        String sequence="";
        FileReader fileReader = new FileReader(file);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        String line = bufferedReader.readLine();
        while(line!=null)
        {
            StringTokenizer tokens = new StringTokenizer(line); 

                    String str;
                    while (tokens.hasMoreTokens()) 
                    {
                        str = tokens.nextToken();
                         if(keywordsId.containsKey(str))
                              sequence= sequence+" "+keywordsId.get(stmWord);
                         else
                         {
                              keywordsId.put(str,id);
                              sequence= sequence+" "+id;
                              id++;
                          }


                         if(keywordsId.size()%10000==0)
                         {
                              bufferedWriter.append(sequence);
                              sequence="";

                               start=id;
                         }

                    }
                    String line = bufferedReader.readLine();
                }
        }

        if(start<id)
        {

              bufferedWriter.append(sequence);
        }

        bufferedReader.close();
        fileReader.close();

        bufferedWriter.close();
         filewriter.close();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }

}

class 的构造函数是:

public ConvertTextToKeywordIds(){
   path= new LocalPath();
   repository= new RepositorySQL();
   keywordsId= new HashMap<String, Integer>();
   id=1;
   start=1;}

我怀疑随着字数的增加,您的程序速度与散列映射的重新散列有关。随着散列映射大小的增长,每次重新散列都会导致显着的时间损失。您可以尝试估计您期望的唯一单词的数量,并使用它来初始化哈希映射。

如@JB Nizet 所述,您可能希望直接写入缓冲写入器,而不是等待累积大量条目。由于缓冲写入器已经设置为仅在积累了足够的更改时才写入。

您最有效的性能提升可能是使用 StringBuilder 而不是 String 来实现您的 sequence

我也会在每次超过一定长度时写入并刷新 sequence,而不是每当您向地图添加 10000 个单词时。

这张地图可能会变得很大 - 您是否考虑过改进它?如果您达到数百万个条目,您可能会使用数据库获得更好的性能。