Я пишу приложение, которое поможет улучшить машинные переводы для моей диссертации. Для этого мне требуется огромное количество данных ngram. У меня есть данные из Google, но это не в полезном формате.Оптимизация чтения больших файлов данных в Java
Вот как отформатирован данные от Google:
ngram TAB year TAB match_count TAB page_count TAB volume_count NEWLINE
Вот что я после:
ngram total_match_count_for_all_years
Итак, я написал небольшое приложение для запуска через файлы и вытащить ngrams и суммировать данные за несколько лет, чтобы получить общий счет. Это, кажется, прекрасно. Но, так как файлы Google настолько большие (по 1,5 ГБ каждый, их 99). <), это занимает много времени, чтобы пройти через все их.
Вот код:
public class mergeData
{
private static List<String> storedNgrams = new ArrayList<String>(100001);
private static List<String> storedParts = new ArrayList<String>(100001);
private static List<String> toWritePairs = new ArrayList<String>(100001);
private static int rows = 0;
private static int totalFreq = 0;
public static void main(String[] args) throws Exception
{
File bigram = new File("data01");
BufferedReader in = new BufferedReader(new FileReader(bigram));
File myFile = new File("newData.txt");
Writer out = new BufferedWriter(new FileWriter(myFile));
while (true)
{
rows = 0;
merge(in, out);
}
}
public static void merge(BufferedReader in, Writer out) throws IOException
{
while (rows != 1000000)
{
storedNgrams.add(in.readLine());
rows++;
}
while (!(storedNgrams.isEmpty()))
{
storedParts.addAll(new ArrayList<String>(Arrays.asList(storedNgrams.get(0).split("\\s"))));
storedNgrams.remove(0);
}
while (storedParts.size() >= 8)
{
System.out.println(storedParts.get(0) + " " + storedParts.get(1) + " " + storedParts.get(6)
+ " " + storedParts.get(7));
if (toWritePairs.size() == 0 && storedParts.get(0).equals(storedParts.get(6))
&& storedParts.get(1).equals(storedParts.get(7)))
{
totalFreq = Integer.parseInt(storedParts.get(3)) + Integer.parseInt(storedParts.get(9));
toWritePairs.add(storedParts.get(0));
toWritePairs.add(storedParts.get(1));
toWritePairs.add(Integer.toString(totalFreq));
storedParts.subList(0, 11).clear();
}
else if (!(toWritePairs.isEmpty()) && storedParts.get(0).equals(toWritePairs.get(0))
&& storedParts.get(1).equals(toWritePairs.get(1)))
{
int totalFreq = Integer.parseInt(storedParts.get(3))
+ Integer.parseInt(toWritePairs.get(2));
toWritePairs.remove(2);
toWritePairs.add(Integer.toString(totalFreq));
storedParts.subList(0, 5).clear();
}
else if ((!toWritePairs.isEmpty())
&& !(storedParts.get(0).equals(storedParts.get(6)) && storedParts.get(1).equals(
storedParts.get(7))))
{
toWritePairs.add(storedParts.get(0));
toWritePairs.add(storedParts.get(1));
toWritePairs.add(storedParts.get(2));
storedParts.subList(0, 2).clear();
}
else if (!(toWritePairs.isEmpty()))
{
out.append(toWritePairs.get(0) + " " + toWritePairs.get(1) + " " + toWritePairs.get(2)
+ "\n");
toWritePairs.subList(0, 2).clear();
}
out.flush();
}
}
}
Если у кого есть какие-либо идеи, как улучшить скорость обработки этих файлов, это помогло бы мне безмерно.
Зачем вам когда-либо читать и обрабатывать более одной строки за раз? вы делаете около 5 раз больше работы, чем вам нужно. –
Спасибо, спасибо, спасибо! : D По какой-то причине, делая это по одной строке за раз, мне не приходило в голову. Теперь, когда я удалил все строки и делаю это по очереди, это очень быстро. –