Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Что быстрее BufferedReader.readLine() ? Сильно много ест процессорного времени 
:(
    Опции темы
Aerodron
Дата 7.4.2008, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 28.9.2007
Где: Украина, Днепропе тровск

Репутация: нет
Всего: 1



Доброго впемени суток.

Столкнулись со следущей проблеммой: При работе сервера, он ждет пакеты от клиентов  в BufferedReader.readLine().
Это место оказалось самым узким в его работе. При этом, работа потока с readLine съедала в среднем около 98% процессорного времени. Какой альтернативный вариант можно использовать для чтения данных, который использовал бы хотябы в половину меньше процессорного времени?

Вот часть кода, которая работает с readLine() :
Код

BufferedReader input = new BufferedReader(new InputStreamReader(in), 512);
while ((null != (s = input.readLine()))) {
    if(StringWizard.stringNotEmpty(s))
        ...
}

PM MAIL ICQ Jabber   Вверх
LSD
Дата 7.4.2008, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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.
PM MAIL WWW   Вверх
Aerodron
Дата 7.4.2008, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 28.9.2007
Где: Украина, Днепропе тровск

Репутация: нет
Всего: 1



Пробовал размер буфера менять до 2 кБ - эффект практически незаметен. Средняя загруженность практически одинакова.

Пакеты очень разные по величине. Самый маленький 52 байт. А есть и больше 2 кБ, но они встречаются нечасто.

То что 98% процессорного времени приходится на метод readLine() посчитала тулза - YourKit Java ProFiler.
Может, я неправильно интерпретировал ее статистику. Вот на всякий случай, ее данные:

user posted image

А читать построчно надо потому, что все пакеты оканчиваются на символ окончания строки.

Это сообщение отредактировал(а) Aerodron - 7.4.2008, 15:27
PM MAIL ICQ Jabber   Вверх
COVD
Дата 7.4.2008, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Может, измерительный инструмент показывает время ожидания, а не процессорное время. Большую часть времемени процесс ожидает данных в readLine, т.е. стоит. Если данные поступают из сети ( с базы данных, с другого компьютера) и сеть или удаленный компьютер тормозят, то при чем здесь BufferedReader?  Читайте в отдельном потоке, чтобы медленный источник данных не замораживал все приложение. 
ps. А с размером буфера не морочьте себе голову - используйте default. 

Это сообщение отредактировал(а) COVD - 7.4.2008, 15:52
PM MAIL   Вверх
Aerodron
Дата 7.4.2008, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 28.9.2007
Где: Украина, Днепропе тровск

Репутация: нет
Всего: 1



Цитата

Может, измерительный инструмент показывает время ожидания, а не процессорное время. 

Это именно процессорное время.

Цитата

Большую часть времемени процесс ожидает данных в readLine, т.е. стоит. 

Тогда почему в это время должен грузиться процессор даже в виндовом мониторе?

Запущено около 200 потоков, которым приходят пакеты каждые полсекунды сбъемом примерно 200 байт. Это нагрузочное тестирование сервера. Процессор загружен практически на 100%. 
Profiler показывает, что большая часть нагрузки приходится именно на этот метод - readLine().
Задача - уменьшить нагрузку на сервер.
PM MAIL ICQ Jabber   Вверх
COVD
Дата 7.4.2008, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Метод readLine использует блокирующий метод read класса Reader. Это означает, что в отсутствие данных поток должен стоять. Буферизация в BufferedReader означает, что он пытается читать "вперед" при каждом вызове readLine, т.е. если данных пришло больше чем одна строка, то он все данные прочитает в буфер, но вернет только одну строку. Никаких подводных камней здесь вроде нет. Альтернативно можно использовать NIO - тогда можно избавиться от 200 потоков.
PM MAIL   Вверх
w1nd
Дата 8.4.2008, 08:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 20
Всего: 54



Цитата(Aerodron @  7.4.2008,  16:26 Найти цитируемый пост)
Это именно процессорное время.

Это не процессорное время, а время выполнения теста. Вы просто видите, что readLine() выполнялся бОльшую часть времени. На что бы вы не поменяли readLine(), картина будет такой же.

Это сообщение отредактировал(а) w1nd - 8.4.2008, 10:55


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
mindflyer
Дата 9.4.2008, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 20.10.2004
Где: Smolensk, Russia

Репутация: 1
Всего: 4



Хм, скорее всего, это время работы метода, т.е. с учётом ожидания. Во всяком случае, в моей практике в подобных местах (ввод/вывод) было именно так.
PM MAIL ICQ   Вверх
LSD
Дата 9.4.2008, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(mindflyer @  9.4.2008,  19:03 Найти цитируемый пост)
Хм, скорее всего, это время работы метода, т.е. с учётом ожидания. Во всяком случае, в моей практике в подобных местах (ввод/вывод) было именно так.

Ожидание на 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.
PM MAIL WWW   Вверх
mindflyer
Дата 11.4.2008, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 20.10.2004
Где: Smolensk, Russia

Репутация: 1
Всего: 4



Цитата(LSD @  9.4.2008,  18:20 Найти цитируемый пост)
Ожидание на IO не потребляет процессорное время. 

Я хотел сказать, что в используемом мною профайлере (JProfiler) по-дефолту показывалось именно полное время работы метода, а не затраченное процессорное время. Вероятно, это можно настроить - не искал, не было такой надобности, но эту особенность для себя отметил.
PM MAIL ICQ   Вверх
Aerodron
Дата 22.4.2008, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 28.9.2007
Где: Украина, Днепропе тровск

Репутация: нет
Всего: 1



Спасибо всем. Это, вероятнее всего, и есть время работы метода, а не затраченное процессорное время. 
(Интересно, каким образом можно вообще измерить процессорное время. Время ведь, скорее всего, замеряется в начале работы метода и в конце работы, а чтобы померять нагрузку на процессор... наверное нужно мерять время работы каждой комманды процессора, а это очень и очень затратно и считать их общее время в методе, что в итоге на порядок замедлит работу)
То есть, именно время работы метода тратилось на IO, но
Цитата

Ожидание на IO не потребляет процессорное время.

в итоге - просто пришлось считать нагрузку, не учитывая ReadLine.
Всем спасибо.
PM MAIL ICQ Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0853 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.