1

我写了一个应用程序,它在它的一个模块中解析巨大的文件并将这个文件逐块保存到数据库中。

首先,以下代码有效,我的主要问题是减少内存使用和总体性能提高。

下面的代码片段只是大图的一小部分,但是在进行了一些 YourKit 分析之后问题最大,由/*Here*/标记的行分配了大量的内存。

....
Scanner fileScanner = new Scanner(file,"UTF-8");
String scannedFarm;
try{

    Pattern p = Pattern.compile("(?:^.++$(?:\\r?+\\n)?+){2,100000}+",Pattern.MULTILINE);
    String [] tableName = null;

/*HERE*/while((scannedFarm = fileScanner.findWithinHorizon(p, 0)) != null){
         boolean continuePrevStream = false;
         Scanner scanner = new Scanner(scannedFarm);

         String[] tmpTableName  = scanner.nextLine().split(getSeparator());
         if (tmpTableName.length==2){
             tableName = tmpTableName;
         }else{
             if (tableName==null){
                 continue;
             }
             continuePrevStream = true;
         }
         scanner.close();

/*HERE*/ InputStream is = new ByteArrayInputStream(scannedFarm.getBytes("UTF-8"));
....

分配大量内存是可以接受的,因为字符串很大(我也需要这么大的块),我的主要问题是由于getBytes,相同的分配发生了两次,

  1. 所以我的问题是他们将findWithinHorizo​​n Result 直接传输到InputStream而不分配内存两次的方法?

  2. 他们是实现相同功能的更有效方式吗?

4

1 回答 1

0

不完全相同的方法,但findWithinHorizon您可以尝试阅读每一行并在行上下文中搜索模式。这肯定会减少内存压力,因为您没有像 API 所述那样缓冲整个文件:

如果horizo​​n 为0,则horizo​​n 被忽略,并且此方法继续搜索输入以寻找指定的模式而不受限制。在这种情况下,它可能会缓冲所有搜索模式的输入

就像是:

while(String line = fileScanner.nextLine() != null) { 
   if(grep for pattern in line) { 

   }
}
于 2013-01-21T20:18:39.870 回答