Что является чистым способом выполнения кода в Java? - PullRequest
0 голосов
/ 23 октября 2018

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

long start = System.nanoTime();

// The code you want to time

long end = System.nanoTime();
System.out.printf("That took: %d ms.%n", TimeUnit.NANOSECONDS.toMillis(end - start));

Попытка

Я пришелКроме того, выглядит лучше, есть несколько преимуществ и недостатков:

Преимущества:

  • Понятно, что происходит из-за отступа
  • Он автоматически выведет, сколько времени прошло после завершения кода

Недостатки:

  • Это не тот способ, которым предполагается использовать AutoClosable (уверен)
  • Создает новый экземпляр TimeCode, который не годится
  • Переменные, объявленные в блоке try, недоступны вне его

Может бытьиспользуется следующим образом:

 try (TimeCode t = new TimeCode()) {
     // The stuff you want to time
 }

Код, который делает это возможным:

class TimeCode implements AutoCloseable {

    private long startTime;

    public TimeCode() {
        this.startTime = System.nanoTime();
    }

    @Override
    public void close() throws Exception {
        long endTime = System.nanoTime();
        System.out.printf("That took: %d ms%n",
                TimeUnit.NANOSECONDS.toMillis(endTime - this.startTime));
    }

}

Вопрос

Мой вопрос:

  • Является ли мой метод на самом деле так плохо, как я думаю, это
  • Есть лилучший способ для таймирования выполнения кода в Java, где вы можете четко видеть, что происходит по расписанию, или мне просто придется довольствоваться чем-то вроде моего первого блока кода.

Ответы [ 4 ]

0 голосов
/ 29 ноября 2018

Я думаю, что решение, предложенное в тексте вопроса, является слишком косвенным и не идиоматическим , чтобы подходить для производственного кода.(Но это похоже на аккуратный инструмент, позволяющий быстро определить время выполнения проекта.)

И проект Guava , и Apache Commons включают stop-смотреть занятия .Если вы используете какой-либо из них, код будет легче читать и понимать, и эти классы также имеют больше встроенных функций.

Даже без использования оператора try-with-resource измеряемый раздел можетбыть заключенным в блок для улучшения ясности:

// Do things that shouldn't be measured

{
    Stopwatch watch = Stopwatch.createStarted();

    // Do things that should be measured

    System.out.println("Duration: " + watch.elapsed(TimeUnit.SECONDS) + " s");
}
0 голосов
/ 23 октября 2018

Ваш метод великолепен как есть.Мы профессионально используем нечто подобное, но написанное на C #.

Одна вещь, которую я потенциально мог бы добавить, это правильная поддержка журналирования, чтобы вы могли переключать эти показатели производительности или иметь их на уровне отладки или информации.

Дополнительные улучшения, которые я хотел бы рассмотреть, - это создание некоторого статического состояния приложения (злоупотребление локальными потоками), чтобы вы могли вкладывать эти разделы и иметь сводные разбивки.

См. https://github.com/aikar/minecraft-timingsдля библиотеки, которая делает это для моддинга Minecraft (написано на Java).

0 голосов
/ 23 октября 2018

У вас просто отличное решение.

Менее выразительный способ - обернуть ваш код в лямбду-таймер.

public void timeCode(Runnable code) {
    ...
    try {
        code.run();
    } catch ...
    }
    ...
}

timeCode(() -> { ...code to time... });

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

0 голосов
/ 23 октября 2018

Вместо того, чтобы каждый раз вызывать методы производительности, запишите аспект.

@Pointcut("(execution(* com.resources.delegate.*.*(..)) "
        + "|| execution(* com.resources.implementation.*.*(..))) ")
public void resourceLayerPointCut() {
}

@Pointcut("(execution(* com.models.delegate.*.*(..)) "
        + "|| execution(* com.repo.implementation.*.*(..))) ")
public void exclusionsPointcut() {
}

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

@Around(value = "resourceLayerPointCut() && exclusionsPointcut()")
public Object aroundResourceLayerMethods(ProceedingJoinPoint code) throws Throwable {
    long startTime = System.currentTimeMillis();
    Object returnValue = null;
  try {

        //This will call your methods

        returnValue = code.proceed();
     } catch (Throwable e) {
        log(joinPoint, startTime, returnValue, Layer.ResourceLayer, true);
        throw (e);
    }

    long endTime = System.currentTimeMillis();
    System.out.printf("That took: %d ms%n", endTime - this.startTime);
    return returnValue;

}
...