2017-01-16 6 views
2

Я распараллеливаю довольно сложную программу, чтобы получить ее быстрее. Для этого я использую большую часть времени ExecutorService. До сих пор это работало очень хорошо, но потом я заметил, что только одна строка кода заставляет мою программу работать как можно быстрее. Это линия с exactScore.get().ExecutorService Future :: получите очень медленный

Я не знаю почему, но иногда требуется больше 0,1 с, чтобы получить двойное значение объекта будущего.

Почему это? Как я могу справиться с этим, что он работает быстрее? Есть ли способ написать непосредственно в Double[] при многопоточности? СООБЩЕНИЕ

int processors = Runtime.getRuntime().availableProcessors(); 
    ExecutorService service = Executors.newFixedThreadPool(processors); 

    // initialize output 
    Double[] presortedExScores = new Double[sortedHeuScores.length]; 

    for(int i =0; i < sortedHeuScores.length; i++){ 
     final int index = i; 
     final Collection<MolecularFormula> formulas_for_exact_method = multimap.get(sortedHeuScores[i]); 
     for (final MolecularFormula formula : formulas_for_exact_method){ 
      Future<Double> exactScore = service.submit(new Callable<Double>() { 
       @Override 
       public Double call() throws Exception { 
        return getScore(computeTreeExactly(computeGraph(formula))); 
       } 
      }); 
      presortedExScores[index] = exactScore.get(); 
     } 

    } 

ответ

2

Этого следовало ожидать. Тогда это не «медленнее»; он просто выполняет свою работу.

Из Javadoc для get():

Уэйтс если это необходимо для вычисления, чтобы закончить, а затем возвращает результат.

Короче говоря: кажется, что вы не понимаете концепций, которые вы используете в своем коде. Идея Будущее заключается в том, что он делает вещи в некоторый момент в будущем.

И позвонив по телефону get(), вы выражаете: я не возражаю ждать сейчас до тех пор, пока результаты этого вычисления «позади» этого Будущего станут доступными.

Таким образом: вам нужно снова отступить и заглянуть в свой код; понять, как ваши разные «потоки деятельности» действительно работают; и как/когда они возвращаются вместе.

Одна идея, которая приходит на ум: прямо сейчас вы создаете свои объекты Future в цикле; и сразу после создания Будущего, вы вызываете на него get(). Это полностью противоречит идее создания нескольких фьючерсов. Другими словами: вместо того, чтобы идти:

foreach X 
    create future X.i 
    wait/get future X.i 

вы могли бы сделать что-то вроде

foreach X 
    create future X.i 

foreach X 
    wait/get for future X.i 

Другими словами: разрешить фьючерсы действительно делать вещи параллельно; вместо принудительного применения последовательный обработка.

Если это не помогает «достаточно», то, как сказано: вы должны посмотреть на свой общий дизайн и определить, есть ли способы дальнейшего «разделить» вещи. Сейчас вся деятельность происходит «тесно» вместе; и удивление: когда вы делаете много работы одновременно, это требует времени. Но, как вы могли догадаться: такой перепроект может быть большой работой; и почти невозможно, не зная больше о вашей проблеме/базе кода.

Более сложный подход заключается в том, что вы пишете код, в котором у каждого Будущего есть способ выразить «Я сделан» - тогда вы «только» начнете все фьючерсы; и подождите, пока последний не вернется. Но, как сказано; Я не могу разработать полное решение для вас здесь.

Другие действительно важные вынос здесь: не просто слепо использовать какой-то код, который «происходит» для работы.Одной из сущностей программирования является понимание каждой концепции, используемой в вашем исходном коде. У вас должно быть довольно хорошее представление о том, что делает ваш код перед тем, как запустил его и нашел «о, что get() делает вещи медленными».

+0

так было бы лучше, если я не попытаюсь получить его уже в цикле for? Поскольку, если я правильно вас понимаю, другие Исполнители не получат заданий, пока мой точныйScor.get не будет завершен (так что в это время нет новых многопотоков). – user312549

+0

См. Мои различные обновления. Это может помочь разбить вещи на две петли; но это действительно зависит от того, что выходит за рамки простого обсуждения вопросов и ответов SO. – GhostCat

 Смежные вопросы

  • Нет связанных вопросов^_^