Правило 0: Прочитайте авторитетную статью о JVM и микро-бенчмаркинге. Хорошая статья - Брайан Гетц, 2005. Не ожидайте слишком многого от микро-бенчмарков; они измеряют лишь ограниченный диапазон характеристик производительности JVM.
Правило 1: Всегда включайте фазу прогрева, которая полностью запускает ваше тестовое ядро, достаточную для запуска всех инициализаций и компиляций перед фазой (фазами) синхронизации. (На этапе прогрева допустимо меньшее количество итераций. Эмпирическое правило - несколько десятков тысяч итераций внутреннего цикла.)
Правило 2: Всегда запускайте с -XX:+PrintCompilation, -verbose:gc и т.д., Чтобы вы могли убедиться, что компилятор и другие части JVM не выполняют непредвиденную работу на этапе синхронизации.
Правило 2.1: Выводите сообщения в начале и конце фаз синхронизации и прогрева, чтобы вы могли убедиться, что на этапе синхронизации нет выходных данных из правила 2.
Правило 3: Помните о разнице между -client и -server, а также OSR и обычными компиляциями. Флаг -XX:+PrintCompilation сообщает о компиляциях OSR со знаком at для обозначения не начальной точки входа, например: Trouble$1::run @ 2 (41 bytes). Предпочитайте сервер клиенту, а обычный OSR - OSR, если вам нужна максимальная производительность.
Правило 4: Помните об эффектах инициализации. Не печатайте в первый раз на этапе синхронизации, поскольку печать загружает и инициализирует классы. Не загружайте новые классы вне фазы прогрева (или фазы заключительного отчета), если только вы специально не тестируете загрузку классов (и в этом случае загружайте только тестовые классы). Правило 2 - это ваша первая линия защиты от подобных эффектов.
Правило 5: Помните об эффектах деоптимизации и перекомпиляции. Не используйте какой-либо путь к коду в первый раз на этапе синхронизации, потому что компилятор может отбросить и перекомпилировать код, основываясь на более раннем оптимистичном предположении, что путь вообще не собирался использоваться. Правило 2 - это ваша первая линия защиты от подобных эффектов.
Правило 6: Используйте соответствующие инструменты, чтобы читать мысли компилятора и ожидать, что код, который он создает, будет удивлен. Проверьте код самостоятельно, прежде чем строить теории о том, что делает что-то быстрее или медленнее.
Правило 7: Уменьшите шум в ваших измерениях. Запустите свой бенчмарк на тихой машине и запустите его несколько раз, отбрасывая выбросы. Используйте -Xbatch для сериализации компилятора с приложением и рассмотрите возможность настройки -XX:CICompilerCount=1 для предотвращения параллельной работы компилятора с самим собой. Делайте все возможное, чтобы уменьшить накладные расходы на сборку данных, устанавливайте Xmx(достаточно большие) equals Xms и используйте UseEpsilonGC, если это доступно.
Правило 8: Используйте библиотеку для своего бенчмарка, поскольку она, вероятно, более эффективна и уже была отлажена исключительно для этой цели. Такой как JMH, Caliper или отличные бенчмарки Билла и Пола UCSD для Java.
Ответ 2
I know this question has been marked as answered but I wanted to mention two libraries that help us to write micro benchmarks
Warm up the JIT first by running the code several times before timing it
Make sure you run it for long enough to be able to measure the results in seconds or (better) tens of seconds
While you can't call System.gc() between iterations, it's a good idea to run it between tests, so that each test will hopefully get a "clean" memory space to work with. (Yes, gc() is more of a hint than a guarantee, but it's very likely that it really will garbage collect in my experience.)
I like to display iterations and time, and a score of time/iteration which can be scaled such that the "best" algorithm gets a score of 1.0 and others are scored in a relative fashion. This means you can run all algorithms for a longish time, varying both number of iterations and time, but still getting comparable results.
I'm just in the process of blogging about the design of a benchmarking framework in .NET. I've got a couple of earlier posts which may be able to give you some ideas - not everything will be appropriate, of course, but some of it may be.
Ответ 4
jmh is a recent addition to OpenJDK and has been written by some performance engineers from Oracle. Certainly worth a look.
The jmh is a Java harness for building, running, and analysing nano/micro/macro benchmarks written in Java and other languages targetting the JVM.