Вы могли также взглянуть на тестирование использования Groovy. В Groovy можно легко дразнить интерфейсы Java с помощью 'как' оператор:
def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest
Кроме этой основной функциональности Groovy предлагает намного больше на передней стороне насмешки, включая мощное MockFor
и StubFor
классы.
Мой опыт работы с файлами большего размера показал, что java.nio
быстрее чем java.io
. Намного быстрее. Как в диапазоне> 250%. Тем не менее, я устраняю очевидные узкие места, от которых, как я полагаю, может пострадать ваш микро-тест. Возможные области для исследования:
Размер буфера. В основном у вас есть алгоритм
По моему собственному опыту, этот размер буфера созрел для настройки. Я остановился на 4 КБ для одной части моего приложения, 256КБ для другого. Я подозреваю, что ваш код страдает от такого большого буфера. Выполните несколько тестов с буферами 1 КБ, 2 КБ, 4 КБ, 8 КБ, 16 КБ, 32 КБ и 64 КБ, чтобы убедиться в этом сами.
Не выполняйте тесты Java, которые читают и записывают на один и тот же диск.
Если вы это сделаете, тогда вы действительно тестируете диск, а не Java. Я бы также предположил, что если ваш процессор не занят, то вы, вероятно, испытываете другие узкие места.
Не используйте буфер, если он вам не нужен.
Зачем копировать в память, если ваша цель - другая диск или сетевая карта? В случае больших файлов задержка нетривиальна.
Как и другие, используйте FileChannel.transferTo ()
или FileChannel.transferFrom ()
. Ключевым преимуществом здесь является то, что JVM использует доступ ОС к DMA ( Прямой доступ к памяти ), если представить. (Это зависит от реализации, но современные версии Sun и IBM для процессоров общего назначения подходят.) Что происходит, так это то, что данные идут прямо на / с диска, на шину, а затем в место назначения. ... обход любой схемы через ОЗУ или ЦП.
Веб-приложение, над которым я работал днем и ночью, очень тяжело вводит-вывод. Я также проводил микро-тесты и тесты в реальных условиях. И результаты опубликованы в моем блоге, посмотрите:
Используйте производственные данные и среду
Микро-тесты подвержены искажениям. Если есть возможность, постарайтесь собрать данные именно из того, что вы планируете делать, с ожидаемой нагрузкой на ожидаемом оборудовании.
Мои тесты надежны и надежны, потому что они проводились в производственной системе, в мощной системе, в системе под нагрузкой, и собраны в журналах. Не 2,5-дюймовый SATA-накопитель 7200 об / мин моего ноутбука, пока я внимательно наблюдал, как JVM работает с моим жестким диском.
На чем вы работаете? Это важно.
If the thing you want to compare is performance of file copying, then for the channel test you should do this instead:
final FileInputStream inputStream = new FileInputStream(src);
final FileOutputStream outputStream = new FileOutputStream(dest);
final FileChannel inChannel = inputStream.getChannel();
final FileChannel outChannel = outputStream.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
inChannel.close();
outChannel.close();
inputStream.close();
outputStream.close();
This won't be slower than buffering yourself from one channel to the other, and will potentially be massively faster. According to the Javadocs:
Many operating systems can transfer bytes directly from the filesystem cache to the target channel without actually copying them.
My experience is, that NIO is much faster with small files. But when it comes to large files FileInputStream/FileOutputStream is much faster.
Я тестировал производительность FileInputStream по сравнению с FileChannel для декодирования файлов с кодировкой base64. На моих экспериментах я тестировал довольно большой файл, и традиционный io всегда был немного быстрее, чем nio.
FileChannel мог иметь преимущество в предыдущих версиях jvm из-за накладных расходов на синхронизацию в нескольких связанных с io классах, но современные jvm довольно хороши при снятии ненужных блокировок.