Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java: Общие вопросы > Что быстрее BufferedReader.readLine() ? |
Автор: Aerodron 7.4.2008, 14:19 | ||
Доброго впемени суток. Столкнулись со следущей проблеммой: При работе сервера, он ждет пакеты от клиентов в BufferedReader.readLine(). Это место оказалось самым узким в его работе. При этом, работа потока с readLine съедала в среднем около 98% процессорного времени. Какой альтернативный вариант можно использовать для чтения данных, который использовал бы хотябы в половину меньше процессорного времени? Вот часть кода, которая работает с readLine() :
|
Автор: LSD 7.4.2008, 14:23 |
Ну во первых зачем ты сделал такой маленький размер буфера? Во вторых ты уверен, что 98% процессорного времени приходится именно на метод readLine(), а не на всю обработку? В третих читать надо обязательно по строчно (до символа конец строки)? И каков средний размер одного пакета? |
Автор: Aerodron 7.4.2008, 15:26 |
Пробовал размер буфера менять до 2 кБ - эффект практически незаметен. Средняя загруженность практически одинакова. Пакеты очень разные по величине. Самый маленький 52 байт. А есть и больше 2 кБ, но они встречаются нечасто. То что 98% процессорного времени приходится на метод readLine() посчитала тулза - YourKit Java ProFiler. Может, я неправильно интерпретировал ее статистику. Вот на всякий случай, ее данные: http://ipicture.ru/ А читать построчно надо потому, что все пакеты оканчиваются на символ окончания строки. |
Автор: COVD 7.4.2008, 15:48 |
Может, измерительный инструмент показывает время ожидания, а не процессорное время. Большую часть времемени процесс ожидает данных в readLine, т.е. стоит. Если данные поступают из сети ( с базы данных, с другого компьютера) и сеть или удаленный компьютер тормозят, то при чем здесь BufferedReader? Читайте в отдельном потоке, чтобы медленный источник данных не замораживал все приложение. ps. А с размером буфера не морочьте себе голову - используйте default. |
Автор: Aerodron 7.4.2008, 16:26 | ||||
Это именно процессорное время.
Тогда почему в это время должен грузиться процессор даже в виндовом мониторе? Запущено около 200 потоков, которым приходят пакеты каждые полсекунды сбъемом примерно 200 байт. Это нагрузочное тестирование сервера. Процессор загружен практически на 100%. Profiler показывает, что большая часть нагрузки приходится именно на этот метод - readLine(). Задача - уменьшить нагрузку на сервер. |
Автор: COVD 7.4.2008, 17:29 |
Метод readLine использует блокирующий метод read класса Reader. Это означает, что в отсутствие данных поток должен стоять. Буферизация в BufferedReader означает, что он пытается читать "вперед" при каждом вызове readLine, т.е. если данных пришло больше чем одна строка, то он все данные прочитает в буфер, но вернет только одну строку. Никаких подводных камней здесь вроде нет. Альтернативно можно использовать NIO - тогда можно избавиться от 200 потоков. |
Автор: w1nd 8.4.2008, 08:30 |
Это не процессорное время, а время выполнения теста. Вы просто видите, что readLine() выполнялся бОльшую часть времени. На что бы вы не поменяли readLine(), картина будет такой же. |
Автор: mindflyer 9.4.2008, 18:03 |
Хм, скорее всего, это время работы метода, т.е. с учётом ожидания. Во всяком случае, в моей практике в подобных местах (ввод/вывод) было именно так. |
Автор: mindflyer 11.4.2008, 09:49 |
Я хотел сказать, что в используемом мною профайлере (JProfiler) по-дефолту показывалось именно полное время работы метода, а не затраченное процессорное время. Вероятно, это можно настроить - не искал, не было такой надобности, но эту особенность для себя отметил. |
Автор: Aerodron 22.4.2008, 10:34 | ||
Спасибо всем. Это, вероятнее всего, и есть время работы метода, а не затраченное процессорное время. (Интересно, каким образом можно вообще измерить процессорное время. Время ведь, скорее всего, замеряется в начале работы метода и в конце работы, а чтобы померять нагрузку на процессор... наверное нужно мерять время работы каждой комманды процессора, а это очень и очень затратно и считать их общее время в методе, что в итоге на порядок замедлит работу) То есть, именно время работы метода тратилось на IO, но
в итоге - просто пришлось считать нагрузку, не учитывая ReadLine. Всем спасибо. |