![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
Aerodron |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 28.9.2007 Где: Украина, Днепропе тровск Репутация: нет Всего: 1 |
Доброго впемени суток.
Столкнулись со следущей проблеммой: При работе сервера, он ждет пакеты от клиентов в BufferedReader.readLine(). Это место оказалось самым узким в его работе. При этом, работа потока с readLine съедала в среднем около 98% процессорного времени. Какой альтернативный вариант можно использовать для чтения данных, который использовал бы хотябы в половину меньше процессорного времени? Вот часть кода, которая работает с readLine() :
|
|||
|
||||
LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Ну во первых зачем ты сделал такой маленький размер буфера?
Во вторых ты уверен, что 98% процессорного времени приходится именно на метод readLine(), а не на всю обработку? В третих читать надо обязательно по строчно (до символа конец строки)? И каков средний размер одного пакета? -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
Aerodron |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 28.9.2007 Где: Украина, Днепропе тровск Репутация: нет Всего: 1 |
Пробовал размер буфера менять до 2 кБ - эффект практически незаметен. Средняя загруженность практически одинакова.
Пакеты очень разные по величине. Самый маленький 52 байт. А есть и больше 2 кБ, но они встречаются нечасто. То что 98% процессорного времени приходится на метод readLine() посчитала тулза - YourKit Java ProFiler. Может, я неправильно интерпретировал ее статистику. Вот на всякий случай, ее данные: ![]() А читать построчно надо потому, что все пакеты оканчиваются на символ окончания строки. Это сообщение отредактировал(а) Aerodron - 7.4.2008, 15:27 |
|||
|
||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Может, измерительный инструмент показывает время ожидания, а не процессорное время. Большую часть времемени процесс ожидает данных в readLine, т.е. стоит. Если данные поступают из сети ( с базы данных, с другого компьютера) и сеть или удаленный компьютер тормозят, то при чем здесь BufferedReader? Читайте в отдельном потоке, чтобы медленный источник данных не замораживал все приложение.
ps. А с размером буфера не морочьте себе голову - используйте default. Это сообщение отредактировал(а) COVD - 7.4.2008, 15:52 |
|||
|
||||
Aerodron |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 28.9.2007 Где: Украина, Днепропе тровск Репутация: нет Всего: 1 |
Это именно процессорное время.
Тогда почему в это время должен грузиться процессор даже в виндовом мониторе? Запущено около 200 потоков, которым приходят пакеты каждые полсекунды сбъемом примерно 200 байт. Это нагрузочное тестирование сервера. Процессор загружен практически на 100%. Profiler показывает, что большая часть нагрузки приходится именно на этот метод - readLine(). Задача - уменьшить нагрузку на сервер. |
||||
|
|||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Метод readLine использует блокирующий метод read класса Reader. Это означает, что в отсутствие данных поток должен стоять. Буферизация в BufferedReader означает, что он пытается читать "вперед" при каждом вызове readLine, т.е. если данных пришло больше чем одна строка, то он все данные прочитает в буфер, но вернет только одну строку. Никаких подводных камней здесь вроде нет. Альтернативно можно использовать NIO - тогда можно избавиться от 200 потоков.
|
|||
|
||||
w1nd |
|
|||
![]() Вертилятор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1077 Регистрация: 22.3.2006 Где: Москва Репутация: 20 Всего: 54 |
Это не процессорное время, а время выполнения теста. Вы просто видите, что readLine() выполнялся бОльшую часть времени. На что бы вы не поменяли readLine(), картина будет такой же. Это сообщение отредактировал(а) w1nd - 8.4.2008, 10:55 -------------------- ![]() ![]() |
|||
|
||||
mindflyer |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 20.10.2004 Где: Smolensk, Russia Репутация: 1 Всего: 4 |
Хм, скорее всего, это время работы метода, т.е. с учётом ожидания. Во всяком случае, в моей практике в подобных местах (ввод/вывод) было именно так.
|
|||
|
||||
LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Ожидание на IO не потребляет процессорное время. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
mindflyer |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 20.10.2004 Где: Smolensk, Russia Репутация: 1 Всего: 4 |
Я хотел сказать, что в используемом мною профайлере (JProfiler) по-дефолту показывалось именно полное время работы метода, а не затраченное процессорное время. Вероятно, это можно настроить - не искал, не было такой надобности, но эту особенность для себя отметил. |
|||
|
||||
Aerodron |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 28.9.2007 Где: Украина, Днепропе тровск Репутация: нет Всего: 1 |
Спасибо всем. Это, вероятнее всего, и есть время работы метода, а не затраченное процессорное время.
(Интересно, каким образом можно вообще измерить процессорное время. Время ведь, скорее всего, замеряется в начале работы метода и в конце работы, а чтобы померять нагрузку на процессор... наверное нужно мерять время работы каждой комманды процессора, а это очень и очень затратно и считать их общее время в методе, что в итоге на порядок замедлит работу) То есть, именно время работы метода тратилось на IO, но
в итоге - просто пришлось считать нагрузку, не учитывая ReadLine. Всем спасибо. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |