Чтение очень длинной строки из консоли с помощью Java Scanner занимает много времени? - PullRequest
3 голосов
/ 22 ноября 2011

В настоящее время я создаю консольную программу, которая читает одну строку с очень длинной строкой с помощью java Scanner.

Пример данных больше похож на это

50000 целое число в одной строке, разделенной белымпробел,

"11 23 34 103 999 381 ....." until 50000 integer

Эти данные вводятся пользователем через консоль, а не из файла

вот мой код

        System.out.print("Input of integers : ");
        Scanner sc = new Scanner(System.in);
        long start = System.currentTimeMillis();

        String Z = sc.nextLine();

        long end = System.currentTimeMillis();
        System.out.println("String Z created in "+(end-start)+"ms, Z character length is "+Z.length()+" characters");

Затем я выполняю, в результате я 'у меня есть это

String Z created within 49747ms, Z character length is 194539 characters

Мой вопрос, почему это занимает много времени?Есть ли какой-нибудь более быстрый способ чтения очень длинной строки?

Я пробовал буферизованный ридер, но не сильно отличался ..

String Z created within 41881ms, Z character length is 194539 characters

Ответы [ 2 ]

2 голосов
/ 22 ноября 2011

Похоже, что сканер использует регулярное выражение для сопоставления с концом строки - это, вероятно, вызывает неэффективность, особенно если вы сопоставляете регулярное выражение со строкой длиной 200 КБ.

Используемый шаблон, по сути,. * (\ R \ n | [\ n \ r \ u2028 \ u2029 \ u0085]) |. + $

0 голосов
/ 22 ноября 2011

Я предполагаю, что будет выделение памяти, так как он читает строку и заполняет буфер символов. И он становится все больше и больше и должен копировать весь до сих пор прочитанный текст снова и снова. Каждый раз он увеличивает внутренний буфер в N раз, поэтому он не является ужасно медленным, но для вашей огромной строки он все еще медленный.

И обработка самого регулярного выражения тоже не помогает. Но я предполагаю, что перераспределение и копирование являются источником замедления.

А может, для освобождения памяти, которую нужно приобрести, нужно сделать GC, так что еще одно замедление.

Вы можете проверить мою гипотезу, скопировав Scanner и изменив значение BUFFER_SIZE на длину вашей строки (или, конечно, больше).

...