Java: Эффективность readLine метода BufferedReader и возможных альтернатив

Мы работаем, чтобы уменьшить задержку и увеличить выполнение процесса, записанного в Java, который использует данные (xml строки) от сокета через readLine () метод класса BufferedReader. Данные разграничены к концу разделителя строки (\n), и каждая строка может иметь переменную длину (6 кбит - 32 кбита). Наш код похож:

Socket sock = connection;
InputStream in = sock.getInputStream();
BufferedReader inputReader = new BufferedReader(new InputStreamReader(in));
...
do 
{
   String input = inputReader.readLine();
   // Executor call to parse the input thread in a seperate thread
}while(true)

Таким образом, у меня есть несколько вопросов:

  • Будет inputReader.readLine () возврат метода, как только он поражает \n символ, или он будет ожидать, пока буфер не будет полон?
  • Существует ли более быстрое из взятия данных из сокета, чем использование BufferedReader?
  • Что происходит, когда размер входной строки меньше, чем размер Сокета получает буфер?
  • Что происходит, когда размер входной строки больше, чем размер Сокета получает буфер?

Я справляюсь (медленно) с библиотеками IO Java, таким образом, любые указатели очень ценятся.

Спасибо!

12
задан Luhar 7 May 2010 в 11:44
поделиться

3 ответа

Вернется ли метод inputReader.readLine(), как только получит символ \n или будет ждать, пока буфер не заполнится?

  • Вернется, как только получит новую строку.

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

  • BufferedReader подразумевает некоторое копирование данных. Можно попробовать NIO apis, который позволяет избежать копирования, но прежде чем тратить на это время, лучше провести анализ, чтобы понять, действительно ли узким местом является ввод-вывод. Более простым быстрым решением является добавление BufferedInputStream вокруг сокета, чтобы каждое чтение не ударяло по сокету (неясно, делает ли InputStreamReader какую-либо буферизацию самостоятельно), например.

    new BufferedReader(new InputStreamReader(new BufferedInputStream(in)))

Что произойдет, если размер входной строки меньше размера буфера приема сокета?

  • BufferedReader получит все доступные данные. Затем он будет сканировать эти данные в поисках новой строки. В результате последующие чтения могут уже иметь данные в BufferedReader.

Что происходит, когда размер входной строки больше размера буфера приема сокета?

  • BufferedReader будет читать то, что находится в буфере приема, и поскольку нет новой строки или достигнут конец потока, он будет продолжать читать данные из сокета, пока не найдет EOF или новую строку. Последующие чтения могут блокироваться, пока не появится больше данных.

Подводя итог, можно сказать, что BufferedReader блокирует только в случае крайней необходимости.

15
ответ дан 2 December 2019 в 18:18
поделиться

Одним из преимуществ BufferedReader является то, что он обеспечивает уровень разделения (буфер) между методами ввода (read, readLine и т. Д.), Которые вы use и фактическое чтение сокета, поэтому вам не нужно беспокоиться обо всех случаях вроде «большая часть строки находится в буфере, но вам нужно прочитать другой буфер, чтобы получить \ n» и т. д.

У вас сделали измерение производительности, которое указывает на то, что использование BufferedReader является проблемой для вашего приложения? Если нет, я бы посоветовал вам начать с выбора метода ввода, который обеспечивает желаемую функциональность (линейный ввод, завершаемый \ n, по его звуку), и беспокоиться о том, есть ли «более быстрый» способ сделать это. только если вы обнаружите, что метод ввода является узким местом.

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

3
ответ дан 2 December 2019 в 18:18
поделиться

Ответ на ваш первый вопрос - да и нет. Если буфер уже содержит терминатор строки, он вернется немедленно, однако, если он не содержит терминатора, он попытается заполнить буфер, но не обязательно полностью. Он будет считываться только до тех пор, пока не будут достигнуты какие-либо новые данные (по крайней мере, один символ) или EOF.

Одна из приятных вещей в Java заключается в том, что библиотеки имеют открытый исходный код,поэтому, если у вас есть полная копия JDK, вы можете посмотреть на источник самостоятельно, чтобы ответить на эти типы вопросов. Я использую eclipse в качестве своей IDE, и по умолчанию, если вы наведите курсор на имя класса и нажмете F3, это приведет вас к источнику (именно так я получил ответ выше). Предостережение заключается в том, что при стандартном дистрибутиве исходный код для некоторых внутренних классов / машинного кода недоступен.

Что касается вашего второго вопроса, я бы сказал в целом нет, так как логика, используемая BufferedReader, в целом та же самая, которую любой код должен был бы воссоздать для достижения той же задачи. Единственное, что может замедлить BufferedReader, это то, что внутренне он использует StringBuffer, который синхронизируется, вместо несинхронизированного StringBuilder.

2
ответ дан 2 December 2019 в 18:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: