Раньше я выполнял некоторые тесты производительности и не могу объяснить полученные результаты.
При выполнении теста ниже, если я раскомментирую private final List<String> list = new ArrayList<String>();
, производительность значительно улучшится. На моей машине тест проходит в течение 70-90 мс, когда это поле присутствует против 650 мс, когда он закомментирован.
Я также заметил, что если я изменил оператор печати на System.out.println((end - start) / 1000000);
, тест без переменной пробегает 450-500 мс вместо 650 мс. Он не действует, когда присутствует переменная.
Мои вопросы:
- Кто-нибудь может объяснить коэффициент почти 10 с переменной или без нее, учитывая, что я даже не использую эту переменную?
- Как этот оператор печати может изменить производительность (особенно, поскольку он появляется после окна измерения производительности)?
ps: при запуске последовательно три сценария (с переменной, без переменной, с другим выражением на печать) занимают около 260 мс.
public class SOTest {
private static final int ITERATIONS = 10000000;
private static final int THREADS = 4;
private volatile long id = 0L;
//private final List<String> list = new ArrayList<String>();
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(THREADS);
final List<SOTest> objects = new ArrayList<SOTest>();
for (int i = 0; i < THREADS; i++) {
objects.add(new SOTest());
}
//warm up
for (SOTest t : objects) {
getRunnable(t).run();
}
long start = System.nanoTime();
for (SOTest t : objects) {
executor.submit(getRunnable(t));
}
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
long end = System.nanoTime();
System.out.println(objects.get(0).id + " " + (end - start) / 1000000);
}
public static Runnable getRunnable(final SOTest object) {
Runnable r = new Runnable() {
@Override
public void run() {
for (int i = 0; i < ITERATIONS; i++) {
object.id++;
}
}
};
return r;
}
}
EDIT
Ниже приведены результаты 10 запусков с тремя сценариями:
- без переменной, используя оператор короткой печати
- без переменной, используя оператор long print (печатает один из объектов)
- последовательный запуск (1 поток)
- с переменной
1 657 473 261 74
2 641 501 261 78
3 651 465 259 86
4 585 462 259 78
5 639 506 259 68
6 659 477 258 72
7 653 479 259 82
8 645 486 259 72
9 650 457 259 78
10 639 487 272 79