Несмотря на то, что в моей работе есть много предлагаемых решений, я все еще не удовлетворен временем выполнения, которое они требуют в моем специальном случае.
Рассмотрим большой текстовый файл 35G в формате FASTA, например:
>Protein_1 So nice and cute little fella MTTKKCLQKFHLESLGKLGDSFLKYAISIQLFKSYENHYEGLPSIKKNKIISNAALFKLG YARKILRFIRNEPFDLKVGLIPSDNSQAYNFGKEFLMPSVKMCSRVK* >Protein_2 Fancy incredible description of its function MADDSKFCFFLVSTFLLLAVVVNVTLAANYVPGDDILLNCGGPDNLPDADGRKWGTDIGS […] etc.
Мне нужно извлечь только строки >
.
Использование grep '>' proteins.fasta > protein_descriptions.txt
для достижения этого занимает всего пару минут.
Но с использованием Java 7 это уже работает более 90 минут:
public static void main(String[] args) throws Exception {
BufferedReader fastaIn = new BufferedReader(new FileReader(args[0]));
List<String> l = new ArrayList<String>();
String str;
while ((str = fastaIn.readLine()) != null) {
if (str.startsWith(">")) {
l.append(str);
}
}
fastaIn.close();
// …
}
Кто-нибудь имеет представление о том, как ускорить это до производительности grep
?
Ваша помощь будет высоко оценена. Ура!
Программа biojava.org предоставляет читателю fasta. Для чтения огромных файлов вам нужно будет рассмотреть использование SeekableByteChannell и использование ByteBuffers. В библиотеке biojava используются байтовые буферы.
Если вы напишете его в outfile немедленно, вместо того, чтобы накапливать объекты в памяти, это улучшит производительность (и будет больше похоже на то, что вы сделали с grep в любом случае).
...
BufferedWriter fastaOut = new BufferedWriter(new FileWriter(args[1]));
...
while ((str = fastaIn.readLine()) != null) {
if (str.startsWith(">")) {
fastaOut.write(str);
fastaOut.newLine();
}
}
...
fastaOut.close();
ArrayList
. В худшем случае это взорвет вашу физическую память, и ваша ОС начнет обмениваться. И когда это происходит, производительность резко падает. Но даже если ваша память достаточно велика, производительность JVM вполне может упасть, так как она получает все больше и больше работы с управлением памятью и сборкой мусора. Используйте статистику своей ОС, чтобы узнать, сколько памяти и процессора использует ваш процесс.
ObjectOutputStream
, чтобы впоследствии можно было загружать его очень быстро. Как мне это сделать?
Возможно, вы могли бы значительно ускорить это, используя несколько потоков. Если файл имеет длину X байтов и у вас есть n потоков, вы начинаете каждый поток с интервалов X/n и читаете X/n байты. Вы хотите синхронизировать свой ArrayList, чтобы убедиться, что ваши результаты добавлены правильно