1

50,000 개의 개체 컬렉션을 고려하십시오. 각 객체는 doWork() 메소드를 통해 반복 당 10 개의 두 배를 생성합니다.이것을 병렬로 구현하는 가장 효율적인 방법은 무엇입니까?

각 50,000 개의 객체를 처리하는 연속적인 while 루프가 있으며 은 doWork()를 호출합니다. 이렇게 생성 된 10 개의 doubles 각각은 각각에 대해 process()를 호출하여 처리되어야합니다.

while 루프 내의 마지막 단계는 각 반복에서 생성 된 복식을 합한 다음 출력을 로깅해야합니다.

디자인은 doWork() 및 process()를 완료하는 데 걸리는 상대적 시간에 따라 좌우됩니까?

이 알고리즘을 구현하는 가장 빠르고 효율적인 CPU 효율적인 방법은 무엇입니까?

나는

내가 ExecutorService를 또는 ForkJoin를 사용해야 ... 멀티 코어의 사용은 많은 도움이 될 것입니다 만드는 상상?

작업을 어떻게 분할해야합니까?

List<A> listA = new ArrayList<>(); 
populateWith50k(listA); // has 50k objects after this line 
List<Double> listB = new ArrayList<>(); 

while(true){ 

    // causes a side affect, hence a change of state that the remaining code 
    // depends on, hence I don't think we can use java streams... 
    changeState(); 

    // the below depends on the system state setup above 
    for (int i=0;i<listA.size();i++){ 
     A a = listA.get(i); 
     a.doWork(); 
     populateUsingA(a); // populates listB, each A creates 10 doubles 
     for (int j=0;j<listB.size();j++){ 
      B b = listB.get(j); 
      b.process(); 
     } 
     sumAndThenLogValuesInListB(a); 
     listB.clear(); 
    } 
} 

답변

2

아마도 병렬 스트림을 사용해야합니다.

listA.parallelStream().flatMapToDouble(A::doWork).sum() 

은 while 루프를 통과 한 합계를 제공합니다. 당신은 즉시 10 개의 double을 출력하기 위해 doWork을 바꾸거나, 그것을하는 또 다른 방법을 소개하거나 그것을하는 더 복잡한 람다 본문을 쓸 필요가있다. (나는 읽기 쉽도록 추천하지 않는다.)

+0

changeState() 메서드에 부작용이있어서 잘 작동하지 않을 수 있습니다. 리팩터링을 통해 복잡성으로 인해 기능 코드 스타일을 더 많이 만들 수 없으며 예제를 단순화하여 더 쉽게 만들 수 있습니다. 이해하다. 죄송합니다. while 루프의 모든 사이클에서 종속 상태가 변경되는 측면 영향에 대한 종속성을 강조하지 않았습니다. – newlogic