Есть ли у Await накладные расходы в тестовом примере

#performance #scala #testing #future #scalatest

#Производительность #scala #тестирование #будущее #масштабирование

Вопрос:

У меня есть очень простые тестовые примеры (масштабируемые, но не имеет значения), и я предоставляю две реализации доступа к некоторым ресурсам, этот метод возвращает либо Try, либо некоторый экземпляр класса case.

Тестовые примеры:

 "ResourceLoader" must
    "successfully initialize resource" in {
    /async code test
    noException should be thrownBy Await.result(ResourceLoader.initializeRemoteResourceAsync(credentials, networkConfig), Duration.Inf)
    }

"ResourceLoader" must
    "successfully sync initialize remote resources" in {
    noException should be thrownBy ResourceLoader.initializeRemoteResource(credentials, networkConfig)
  }
  

Это тестирует тестирование другого кода, который обращается к некоторым удаленным ресурсам

Версия синхронизации

 def initializeRemoteResource(credentials: Credentials, absolutePathToNetworkConfig: String): Resource = {
  //some code accessing remote server
}
  

Асинхронная версия

 def initializeRemoteResourceAsync(credentials: Credentials, absolutePathToNetworkConfig: String): Future[Try[Resource]] = {
  Future {
    //the same code as in sync version
  }
}
  

На вкладке IDEA test я вижу, что будущая версия в два раза медленнее, чем версия sync, мой вопрос: есть ли накладные расходы для Await.result явного вызова? Если нет, то почему это замедляет выполнение? Ценю любую помощь, спасибо.

Примечание: я знаю, что это не лучший способ измерить производительность производственной системы. Но в списке указано, сколько времени было потрачено на каждый тестовый пример.

Ответ №1:

Да, будут небольшие накладные расходы Await.result , но на практике это, вероятно, не так много. Для Future {} требуется ExecutionContext (пул потоков или создатель потоков) в неявной области, поэтому вы не сможете успешно использовать его без импорта контекста выполнения по умолчанию (который просто создаст поток) или какого-либо другого контекста. Например, если вы используете контекст выполнения по умолчанию, у вас будет два потока вместо одного, что повлечет за собой некоторые накладные расходы на переключение контекста. Хотя это не должно быть много. Если «в два раза медленнее» означает 40 мс вместо 20, то, возможно, об этом не стоит беспокоиться.

Комментарии:

1. Что занимает больше времени, вызов Await.result или получение future из пула потоков? Мне действительно интересно, как определить правильный вариант использования для будущей работы. Или насколько трудоемкой должна быть операция, чтобы запускать ее асинхронно, чтобы ускорить работу?

2. Await.result просто блокирует текущий поток до завершения future в фоновом потоке. Сколько времени требуется для получения потока из пула потоков, зависит от того, какой тип ExecutionContext вы используете. Обычно эти вещи выполняются очень быстро, и ввод-вывод занимает на порядок больше времени.