Быстрее, чем Scanner или BufferedReader для чтения многострочных данных из STDIN? - PullRequest
1 голос
/ 02 марта 2011

Примечание: я в настоящее время кодирую в Java.Я хочу прочитать входные данные в строку, по одной строке за раз (или более), и я ожидаю много общих строк.

Сейчас я реализовал

scanner in = new Scanner(System.in)
while (in.hasNextLine()) {
    separated = in.nextLine().split(" ");
    ...
}

потому что внутри строки мои входы разделены пробелом.

К сожалению, с миллионами строк этот процесс ОЧЕНЬ медленный, и он занимает больше времени, чем моя обработка данных, поэтому я заглянул в библиотеки java.io инашел кучу возможностей, и я не уверен, какой из них использовать (ByteArrayInputStream, FileInputStream, BufferedInputStream, PipedInputStream).Какой из них мне следует использовать?

Чтобы указать, что мои данные передаются из текстового файла, каждая строка содержит 4 или 6 слов, оканчивающихся символом новой строки, и мне нужно анализировать по одной строке за раз, установив (4 или 6) слов в массив, которым я могу временно управлять.Формат данных:

392903840 a c b 293 32.90
382049804 a c 390
329084203 d e r 489 384.90
...

Есть ли способ, при котором сканер может считывать около 1000 строк за раз и становится эффективным, или какой из этих типов данных я должен использовать (чтобы минимизировать скорость)?

Примечание: во время эксперимента я попытался:

java.io.BufferedReader stdin = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
while(in.ready()){
    separated = in.readLine().split(" ");
    ...
}

, который работал хорошо, просто задавался вопросом, какой из них работает лучше всего, и если есть какой-либо способ, скажем, прочитать 100 строк в данные сразу, то обработать все.Слишком много вариантов в поисках оптимального решения.

1 Ответ

5 голосов
/ 02 марта 2011

Вы должны обернуть System.in в BufferInputStream как:

BufferedInputStream bis = new BufferedInputStream(System.in);
Scanner in = new Scanner(bis);

, поскольку это сводит к минимуму количество операций чтения в System.in, что повышает эффективность (BufferedInputStream).

Кроме того, если вы только читаете строки, вам на самом деле не нужен Сканер, а Считыватель (который имеет методы readLine() и ready(), чтобы получить новую строку и посмотреть, есть ли еще какие-либо данные для чтения).

Вы бы использовали его как таковой (см. Пример на java6: InputStreamReader ):

(я добавил аргумент размера кэша 32 МБ к BufferedReader)

BufferedReader br = new BufferedReader(new InputStreamReader(System.in), 321024);
while (br.ready()) {
    String line = br.readLine();
    // process line
}

со страницы документа InputStreamReader:

без буферизации, каждый вызов read () или readLine () могут вызывать байты быть прочитанным из файла, преобразованным в символы, а затем вернулся, что может быть очень неэффективно.

*1024*
...