Эффективность в отношении i ++ и amp; ++ i in for loop (Java) [dубликат]

Он называется gnome-software: sudo apt update && sudo apt -y install gnome-software

711
задан 23 May 2017 в 15:26

10 ответов

Я знаю, что этот вопрос отмечен как ответ, но я хотел упомянуть о двух библиотеках, которые позволяют нам записывать микро-тесты

Суппорт из Google

Начальные обучающие программы

http://codingjunkie.net/micro-benchmarking-with-caliper/ http://vertexlabs.co.uk/blog/caliper

Суппорт из Google [ ! d11]

Начальные учебные пособия

http://codingjunkie.net/micro-benchmarking-with-caliper/ http : //codingjunkie.net/micro-benchmarking-with-caliper/ http://vertexlabs.co.uk/blog/caliper
211
ответ дан 15 August 2018 в 16:16

jmh - последнее дополнение к OpenJDK и было написано некоторыми инженерами по производительности из Oracle. Разумеется, стоит посмотреть.

jmh - это Java-жгут для построения, запуска и анализа тестов nano / micro / macro, написанных на Java и других языках, нацеленных на JVM.

Очень интересные фрагменты информации, зарытые в jmh .

См. также:

Избегание ошибок при тестировании JVM на главном сильные стороны jmh.
40
ответ дан 15 August 2018 в 16:16

Важными вещами для тестов Java являются:

Сначала разогреть JIT, запустив код несколько раз, прежде чем синхронизировать его. Убедитесь, что вы запускаете его достаточно долго, чтобы иметь возможность измерять результаты в секундах или ( лучше) десятки секунд. Пока вы не можете вызвать System.gc() между итерациями, неплохо запустить его между тестами, так что каждый тест, мы надеемся, получит «чистую» память для работы. (Да, gc() - скорее намек, чем гарантия, но очень вероятно, что он действительно будет собирать мусор в моем опыте.) Мне нравится показывать итерации и время, а также счет времени / итерации, который можно масштабировать таким образом что «лучший» алгоритм получает оценку 1.0, а другие оцениваются относительно. Это означает, что вы можете запускать все алгоритмы в течение длительного времени, варьируя как количество итераций, так и время, но все же получая сопоставимые результаты.

Я просто занимаюсь ведением блога о дизайне платформы тестирования в .NET. У меня есть несколько ранних сообщений, которые могут дать вам некоторые идеи - конечно, не все будет уместно, но некоторые из них могут быть.

71
ответ дан 15 August 2018 в 16:16
  • 1
    Minor nitpick: IMO ", так что каждый тест получает" должен быть ", чтобы каждый тест мог получить" поскольку первый создает впечатление, что вызов gc всегда освобождает неиспользуемую память. – Sanjay T. Sharma 20 April 2013 в 11:52
  • 2
    @ SanjayT.Sharma: Ну, намерение заключается в том, что это действительно так. Хотя это не строго гарантировано, это на самом деле довольно сильный намек. Будет редактировать, чтобы быть более четким. – Jon Skeet 20 April 2013 в 13:02
  • 3
    Я не согласен с вызовом System.gc (). Это намек, вот и все. Даже «он, надеюсь, что-то сделает». Вы никогда не должны его называть. Это программирование, а не искусство. – gyorgyabraham 14 June 2013 в 15:38
  • 4
    @gyabraham: Да, это намек, но это тот, который я обычно наблюдал. Итак, если вам не нравится использовать System.gc(), как вы предлагаете минимизировать сбор мусора в одном тесте из-за объектов, созданных в предыдущих тестах? Я прагматичен, а не догматичен. – Jon Skeet 14 June 2013 в 15:58
  • 5
    @gyabraham: Я не знаю, что вы подразумеваете под «отличным отступлением». Можете ли вы уточнить, и еще раз - у вас есть предложение дать лучшие результаты? Я прямо сказал, что это не гарантия ... – Jon Skeet 14 June 2013 в 22:44

Если вы пытаетесь сравнить два алгоритма, сделайте по крайней мере два теста на каждом, чередуя порядок. т.е.:

for(i=1..n)
  alg1();
for(i=1..n)
  alg2();
for(i=1..n)
  alg2();
for(i=1..n)
  alg1();

Я обнаружил некоторые заметные различия (иногда 5-10%) во время выполнения одного и того же алгоритма в разных проходах.

Кроме того, убедитесь, что n очень велика, так что время выполнения каждого цикла составляет как минимум 10 секунд или около того. Чем больше итераций, тем более значимые цифры в вашем контрольном времени и более надежные данные.

12
ответ дан 15 August 2018 в 16:16
  • 1
    Естественно, изменение порядка влияет на время выполнения. JVM-оптимизации и кэширование-эффекты будут работать здесь. Лучше всего «разогреть» JVM-оптимизацию, выполнить несколько циклов и протестировать каждый тест в другой JVM. – Mnementh 2 February 2009 в 22:04

Существует множество возможных ошибок для написания микро-тестов в Java.

Во-первых: вам нужно рассчитать всевозможные события, которые требуют более или менее случайного времени: сбор мусора, эффекты кеширования (ОС для файлов и CPU для памяти), IO и т. д.

Второе: вы не можете доверять точности измеренных времен для очень коротких интервалов.

В-третьих: JVM оптимизирует ваш код, пока выполнения. Таким образом, разные запуски в одном и том же экземпляре JVM будут быстрее и быстрее.

Мои рекомендации. Сделайте свой тест за несколько секунд, более надежным, чем время выполнения за миллисекунды. Разогрейте JVM (это означает, что хотя бы один раз тестируйте бенчмарк без измерения, JVM может запускать оптимизацию). И запустите свой тест несколько раз (может быть, 5 раз) и возьмите медианную ценность. Запуск каждого микро-теста в новом JVM-экземпляре (вызов для каждого теста новой Java), в противном случае эффекты оптимизации JVM могут повлиять на последующие тесты. Не выполняйте действия, которые не выполняются в фазе прогрева (поскольку это может вызвать загрузку классов и перекомпиляцию).

12
ответ дан 15 August 2018 в 16:16
Если контрольная точка измеряет время / итерацию или итерации / время и почему?

Это зависит от того, что вы пытаетесь проверить. Если вы заинтересованы в задержке, используйте время / итерацию, и если вы заинтересованы в пропускной способности, используйте итерации / время.

17
ответ дан 15 August 2018 в 16:16

Убедитесь, что вы каким-то образом используете результаты, которые вычисляются в контрольном коде. В противном случае ваш код можно будет оптимизировать.

14
ответ дан 15 August 2018 в 16:16

Чтобы добавить к другому превосходному совету, я также помню следующее:

Для некоторых процессоров (например, Intel Core i5 с TurboBoost) температура (и количество ядер в настоящее время используемый, а также процент использования) влияет на тактовую частоту. Поскольку процессоры динамически синхронизируются, это может повлиять на ваши результаты. Например, если у вас однопоточное приложение, максимальная тактовая частота (с TurboBoost) выше, чем для приложения, использующего все ядра. Таким образом, это может помешать сравнению одно- и многопоточной производительности на некоторых системах. Имейте в виду, что температура и колебания также влияют на продолжительность поддерживаемой частоты Turbo.

Возможно, более принципиально важный аспект, который у вас есть прямое управление: убедитесь, что вы правильно оцениваете! Например, если вы используете System.nanoTime() для тестирования определенного бита кода, поместите вызовы в задание в местах, которые имеют смысл избегать измерения того, что вас не интересует. Например, не делайте:

long startTime = System.nanoTime();
//code here...
System.out.println("Code took "+(System.nanoTime()-startTime)+"nano seconds");

Проблема в том, что вы не сразу получаете время окончания кода. Вместо этого попробуйте следующее:

final long endTime, startTime = System.nanoTime();
//code here...
endTime = System.nanoTime();
System.out.println("Code took "+(endTime-startTime)+"nano seconds");
5
ответ дан 15 August 2018 в 16:16

Следует также отметить, что также может быть важно проанализировать результаты микро-теста при сравнении различных реализаций. Поэтому следует выполнить тест значимости.

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

Так что также важно писать и запускать микро-тест правильно, но и проанализировать его правильно.

7
ответ дан 15 August 2018 в 16:16

http://opt.sourceforge.net/ Java Micro Benchmark - контрольные задачи, необходимые для определения сравнительных характеристик производительности компьютерной системы на разных платформах. Может использоваться для управления решениями по оптимизации и для сравнения различных реализаций Java.

6
ответ дан 15 August 2018 в 16:16
  • 1
    Кажется, просто сравнивает оборудование JVM +, а не произвольную часть кода Java. – Stefan L 1 March 2012 в 04:05

Другие вопросы по тегам:

Похожие вопросы: