2016-12-23 2 views
2

나는 직장에서 흥미로운 발견을했다. RxJava 전문가 중 한 명이 그것을 설명하기를 희망한다. RxJava 1.2.4를 사용하고 있습니다.RxJava - 내 switchMap()이 전환 속도가 느린 이유는 무엇입니까?

나는 TableView (JavaFX 스레드에서 방출 됨)에서 표 선택 이벤트를 방출하기 위해 RxJavaFX을 사용하고 각각에 대해 값 비싼 프로세스를 시작하기 위해 switchMap()에 넣었습니다. 저는 switchMap()subscribeOn()과 함께 사용하여 동시성을 활용할뿐만 아니라 여러 선택을 빠르게하면 이전 요청이 취소되고 다음 요청이 다음에 시작됩니다.

tableSelectionEvents.switchMap { 
     runExpensiveProcess(it) 
       .subscribeOn(Schedulers.io()) 
       .flatMap { anotherExpensiveProcess(it) } 
       .toList() 
    }.observeOn(JavaFxScheduler.getInstance()).subscribe { 
     backingList.setAll(it) 
    } 

그러나, 나는 내가 자바 FX 스레드가 여전히 많은 양의 작업을하고 있던 의미, 선택을 만든 것처럼 자바 FX UI가 무섭게 랙이 알게되었다. 이것은 내가 switchMap() 안에 Schedulers.io()을 사용하여 다른 스레드에서 작업을 오프로드 한 것으로 생각했기 때문에 나에게 당황 스러웠습니다. 실제로이 경우였습니다. 하지만 다른 일이 벌어지고있었습니다.

나는 직감을 가지고 switchMap() 바로 앞에 observeOn(Schedulers.io())을 넣었습니다. 이제 모든 것이 완벽하게 실행되며 지연이 전혀 없습니다. 내 이론은 들어오는 스레드 (원래 JavaFX 스레드, 이제 IO 스레드)가 switchMap() 내부의 마지막 구독을 취소하는 데 상당한 작업을 수행해야한다는 것입니다. 이로 인해 JavaFX 스레드가 취소를 실행하여 UI를 정지시키는 데 상당한 시간을 소비하게되었습니다.

switchMap() 내에서 unSubscribe()을 비싸게 호출하고 있습니까?

+0

'runExpensiveProcess'는 어떻게 구현 되었습니까? – akarnokd

+0

값 비싼 RxJava-JDBC 쿼리가이를 유도합니다. – tmn

답변

4

다른 포럼에서 Jake Wharton으로부터 도움을 받았습니다. 그는 내가 이미 의심하기 시작한 것을 강조했다. 일부 구독은 구독 취소하기 위해 다른 구독보다 비쌉니다. 이 경우, RxJava-JDBC를 사용하여 대량의 쿼리 오버 헤드가 발생하고 JavaFX 스레드가이 작업을 수행하게되었습니다.

그는 또한 이것이 unsubscribeOn() 연산자의 목적이라고 말했습니다. 탈퇴 실행을위한 스케줄러를 지정할 수 있습니다.

tableSelectionEvents.switchMap { 
     runExpensiveProcess(it) 
       .subscribeOn(Schedulers.io()) 
       .flatMap { anotherExpensiveProcess(it) } 
       .toList() 
       .unsubscribeOn(Schedulers.io()) 
    }.observeOn(JavaFxScheduler.getInstance()).subscribe { 
     backingList.setAll(it) 
    }