Проверка нулевой производительности Java - PullRequest
0 голосов
/ 08 июня 2018

Мне было интересно, было ли какое-либо существенное различие при проверке, является ли объект нулевым в Java с помощью прямого сравнения или с помощью метода Objects.isNull ().

public class Test {

  public final static Long ITERATIONS = 100000000L; 

  @Test
  public void noFnCalls() {
    balong startTime = System.currentTimeMillis();
    Object x = new Object();
    Long i;
    for (i = 0L; i < ITERATIONS; i++) {
      boolean t = x == null;
    }
    long estimatedTime = System.currentTimeMillis() - startTime;
    System.out.println("noFnCalls ellapsed time: " + estimatedTime);
  }

  @Test
  public void withFnCalls() {
    long startTime = System.currentTimeMillis();
    Object x = new Object();
    Long i;
    for (i = 0L; i < ITERATIONS; i++) {
      boolean t = Objects.isNull(x);
    }
    long estimatedTime = System.currentTimeMillis() - startTime;
    System.out.println("withFnCalls ellapsed time: " + estimatedTime);
  }
}

И, что удивительно, по крайней мередля меня всегда требуется больше времени, чтобы закончить "noFnCalls".Я ожидал в значительной степени противоположного результата, поскольку он приводит к вызову метода с использованием стека.

Это вывод: (Очевидно, каждый раз меняется, но всегда с "noFnCalls" выше)

noFnCalls истекшее время: 583

withFnCalls истекшее время: 463

Почему это производится?

1 Ответ

0 голосов
/ 08 июня 2018

Результаты, которые вы видите, вероятно, связаны с первым запуском noFnCalls, без надлежащего прогрева перед тестом и измерением.

Я получаю это:

withFnCalls ellapsed time: 444
noFnCalls ellapsed time: 471
withFnCalls ellapsed time: 334
noFnCalls ellapsed time: 331
withFnCalls ellapsed time: 330
noFnCalls ellapsed time: 325
withFnCalls ellapsed time: 331
noFnCalls ellapsed time: 326
withFnCalls ellapsed time: 326
noFnCalls ellapsed time: 328

Использование

import java.util.Objects;

public class Test {

  public final static Long ITERATIONS = 100000000L; 

  public static void main(String args[]) {
    withFnCalls();
    noFnCalls();
    withFnCalls();
    noFnCalls();
    withFnCalls();
    noFnCalls();
    withFnCalls();
    noFnCalls();
    withFnCalls();
    noFnCalls();
  }
  public static void noFnCalls() {
    long startTime = System.currentTimeMillis();
    Object x = new Object();
    Long i;
    for (i = 0L; i < ITERATIONS; i++) {
      boolean t = x == null;
    }
    long estimatedTime = System.currentTimeMillis() - startTime;
    System.out.println("noFnCalls ellapsed time: " + estimatedTime);
  }

  public static void withFnCalls() {
    long startTime = System.currentTimeMillis();
    Object x = new Object();
    Long i;
    for (i = 0L; i < ITERATIONS; i++) {
      boolean t = Objects.isNull(x);
    }
    long estimatedTime = System.currentTimeMillis() - startTime;
    System.out.println("withFnCalls ellapsed time: " + estimatedTime);
  }
}

и

withFnCalls ellapsed time: 3618
noFnCalls ellapsed time: 3361
withFnCalls ellapsed time: 3445
noFnCalls ellapsed time: 3278
withFnCalls ellapsed time: 3350
noFnCalls ellapsed time: 3292
withFnCalls ellapsed time: 3309
noFnCalls ellapsed time: 3262
withFnCalls ellapsed time: 3293
noFnCalls ellapsed time: 3261

Если я увеличу до 1000000000L итераций.Это было сделано с помощью Java 9 64-битного сервера jvm, сборка 9 + 181, от Oracle, работающего на Windows 10 с компьютером с процессором Intel i5-2600.

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

Обязательный рекомендуемый поток о микробанчмаркинге в Java: Как мненаписать правильный микро-тест на Java? .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...