Java [Input|Output]Streams с одним вызовом метода для каждого байта: проблема с производительностью?

[Input|Output]Streams существуют с JDK1.0, а их символьные аналоги Readers|Writers существуют с JDK1.1.

Большинство концепций кажутся похожими, за одним исключением: базовые классы потоков объявляют абстрактный метод, который обрабатывает один один байт за раз, в то время как базовые читатели/писатели< /strong> классы объявляют абстрактный метод, который обрабатывает целые char-массивы.

Таким образом, если я правильно понимаю, каждый переопределенный класс stream ограничен обработкой отдельных байтов (таким образом, выполняется как минимум один вызов метода для каждого байта!), а переопределенный < strong>программам чтения/записи нужен только вызов метода для каждого массива (-буфера).

Разве это не огромная проблема с производительностью?

Может ли поток быть реализован как подкласс InputStream или OutputStream, но тем не менее основываться на byte-массивах?


person java.is.for.desktop    schedule 04.09.2010    source источник


Ответы (5)


На самом деле подклассы InputStream должны переопределять метод, считывающий по одному байту за раз, но также могут переопределять другие методы, считывающие массивы байтов. Я думаю, что это действительно так для большинства потоков ввода/вывода.

Так что, на мой взгляд, это не большая проблема с производительностью, и да, вы можете расширить поток ввода-вывода и основываться на массивах байтов.

person Vivien Barousse    schedule 04.09.2010

Чтение одного байта почти всегда является огромной проблемой производительности. Но если вы читаете документацию API InputStream, вы видите, что вы ДОЛЖНЫ переопределить read(), но ДОЛЖНЫ также переопределить read(byte[],int,int). Большая часть кода, который использует любой вид InputStream, в любом случае вызывает метод стиля массива, но реализация этой функции по умолчанию просто реализуется путем вызова read() для каждого байта, поэтому негативное влияние на производительность.

Для OutputStream то же самое.

person Daniel    schedule 04.09.2010

Как сказал Даниэль, вы должны переопределить read(), так как клиент может использовать его напрямую, но вы также должны переопределить read (byte[],int,int).

Однако я сомневаюсь, что вам следует беспокоиться о производительности, поскольку jvm может и будет встраивать этот метод для вас. Больше всего мне это не кажется проблемой.

Кроме того, большинство читателей используют некоторый базовый входной поток за сценой, поэтому в любом случае эти методы, основанные на массиве символов, в конечном итоге вызывают read(byte[],int,int) или даже read() напрямую.

person Yoni    schedule 04.09.2010

Обратите внимание, что Readers/Writers предназначены для чтения символов, которые могут состоять из большего байта, например символов Юникода. С другой стороны, потоки больше подходят, когда вы имеете дело с нестроковыми (двоичными) данными.

Кроме того, InputStream и OutputStream также имеют методы для чтения/записи всего массива байтов.

person Andre Holzner    schedule 04.09.2010
comment
Я знаю, я говорил об абстрактных методах. Но теперь вы и другие ответчики ясно дали понять, что другие методы также подходят для переопределения. - person java.is.for.desktop; 05.09.2010

с точки зрения производительности, если вы обернете его с помощью BufferedInputStream, JVM должна иметь возможность оптимизировать накладные расходы на однобайтовые вызовы метода чтения до нуля, т.е. это так же быстро, как если бы вы выполняли буферизацию самостоятельно.

person irreputable    schedule 04.09.2010