2017-12-24 40 views
1

내가이 같은 기능을 가지고 가정 : 이제Scala Future의지도에 오버 헤드가 추가됩니까?

import scala.concurrent._ 

def plus2Future(fut: Future[Int]) 
       (implicit ec: ExecutionContext): Future[Int] = fut.map(_ + 2) 

내가 만들 plus2Future를 사용하여 오전 Future 새로운 :

import import scala.concurrent.ExecutionContext.Implicits.global 
val fut1 = Future { 0 } 
val fut2 = plus2Future(fut1) 

는 동일한 스레드로 지금 기능을 plus2항상 실행합니까 fut1? 나는 그렇지 않다고 생각한다.
mapplus2Future에 사용하면 스레드 컨텍스트 전환의 오버 헤드가 추가되어 새로운 Runnable 등이 생성됩니까?

+1

* 스레드 컨텍스트 전환과 관련된 오버 헤드를 방지하려면 * 코드를 벤치마킹 할 때 오버 헤드가 있는지 확인 했습니까? –

+1

동일한 스레드에서 실행하려면 'Future {plus2 (plus1 (x))}'를 수행하십시오. 아니면 단지 'plus2 (plus1 (x))'... 미래를 만드는 "오버 헤드"를 피하기 위해 :) – Dima

+0

@YuvalItzchakov 아니요, 코드를 벤치 마크하지 않았습니다. 나는 그 질문을 바꿔 말할 것이다. – Michael

답변

2

플러스 2에서 맵을 사용합니까? 스레드 컨텍스트의 오버 헤드를 추가하여새 Runnable 만들기? Future (DefaultPromise를 통해)의 기본 구현에

map

은 다음과 같습니다 onComplete 새로운 CallableRunnable를 만들고 결국 호출

def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = { // transform(f, identity) 
    val p = Promise[S]() 
    onComplete { v => p complete (v map f) } 
    p.future 
} 

dispatchOrAddCallback :에 전화를 전달

/** Tries to add the callback, if already completed, it dispatches the callback to be executed. 
* Used by `onComplete()` to add callbacks to a promise and by `link()` to transfer callbacks 
* to the root promise when linking two promises togehter. 
*/ 
@tailrec 
private def dispatchOrAddCallback(runnable: CallbackRunnable[T]): Unit = { 
    getState match { 
    case r: Try[_]   => runnable.executeWithValue(r.asInstanceOf[Try[T]]) 
    case _: DefaultPromise[_] => compressedRoot().dispatchOrAddCallback(runnable) 
    case listeners: List[_] => if (updateState(listeners, runnable :: listeners))() else dispatchOrAddCallback(runnable) 
    } 
} 

기본 실행 컨텍스트 이것은 미래가 어떻게 그리고 어디에서 실행되는지를 결정하는 것이 실행 ExecutionContext에 달려 있다는 것을 의미하므로 "여기저기서 달립니다"라는 결정 론적 답변을 줄 수는 없습니다. Promise과 콜백 객체가 할당되어 있다는 것을 알 수 있습니다.

일반적으로 코드를 벤치마킹하지 않고 병목 현상이 발생하지 않는다면 걱정할 필요가 없습니다.

+0

답해 주셔서 감사합니다. 이제 이것이 기본'ExecutionContext'에서 어떻게 작동하는지 확인하는 것은 흥미 롭습니다. – Michael

+0

병목 현상이 거의 발생하지 않는다는 것에 동의합니다. 어떻게 작동하는지 이해하고 싶습니다. – Michael

+0

@ 마이클 이렇게 : https://github.com/scala/scala/blob/2.12.x/src/library/scala/concurrent/impl/ExecutionContextImpl.scala#L20 (Scala 2.12.x) –

1

아니요, 두 줄의 코드 사이에 제한 시간이 경과 할 수 있기 때문에 동일한 스레드를 사용할 수 없습니다 (EC에는 단 하나의 스레드 만있는 경우 제외).