Разделение циклов на большую итерацию - PullRequest
2 голосов
/ 05 июня 2019

Цель моего вопроса - повысить производительность моего алгоритма, разделив диапазон итераций цикла по большому списку массивов.
Например: у меня есть список Array размером около 10 миллиардов записей длинных значений, цель, которую я пытаюсь достичь, - запустить цикл с 0 до 100 миллионов записей, вывести результат для 100 миллионов записей любых вычислений. внутри петли; затем начинаем и от 100 миллионов до 200 миллионов выполняем предыдущий и выводим результат, затем 300-400 миллионов, 400-500 миллионов и так далее и так далее. после того как я получу все 100 миллиардов / 100 миллионов результатов, я смогу суммировать их вне цикла, собирая результаты с выходов цикла параллельно.

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

public static void tt4() {
    long essir2 = 0;
    long essir3 = 0;

    List cc = new ArrayList<>();  
    List<Long> range = new ArrayList<>();  

    // break point is a method that returns list values, it was converted to 
    // string because of some concatenations and would be converted back to long here
    for (String ari1 : Breakpoint()) {
        cc.add(Long.valueOf(ari1));
    }  

    // the size of the List is huge about 1 trillion entries at the minimum
    long hy = cc.size() - 1;

    for (long k = 0; k < hy; k++) { 
        long t1 = (long) cc.get((int) k);
        long t2 = (long) cc.get((int) (k + 1)); 

        // My main question: I am trying to iterate the entire list in a dynamic way 
        // which would exclude repeated endpoints on each iteration. 

        range = LongStream.rangeClosed(t1 + 1, t2)
                          .boxed()
                          .collect(Collectors.toList());  

        for (long i : range) {
            // Hard is another method call on the iteration
            // complexcalc is a method as well

            essir2 = complexcalc((int) i, (int) Hard(i)); 
            essir3 += essir2;
        } 
    }

    System.out.println("\n" + essir3);  
}

У меня нет ошибок, я просто ищу способ повысить производительность и время. Я могу сделать миллион записей менее чем за секунду, но когда я укажу нужный размер, он будет работать вечно. Размеры, которые я привожу, являются рефератами, иллюстрирующими величины размера, я не хочу, чтобы мнения, как 100 миллиардов, невелики, если я могу сделать миллион за секунду, я говорю о огромных количествах, которые мне нужно повторить, делая сложные задачи и вызовы, мне просто нужна помощь с логикой, которую я пытаюсь достичь, если смогу.

1 Ответ

0 голосов
/ 05 июня 2019

Одна вещь, которую я бы сразу предложил, - это сохранить возвращаемое Breakpoint значение в простом массиве, а не List. Это должно значительно улучшить ваше время выполнения:

    List<Long> cc = new ArrayList<>();
    for (String ari1 : Breakpoint()) {
        cc.add(Long.valueOf(ari1));
    }
    Long[] ccArray = cc.toArray(new Long[0]);

Я считаю, что вам нужно разделить ваши задачи на несколько потоков. Вы можете сделать это с помощью ExecutorService ", который упрощает выполнение задач в асинхронном режиме" .

Обратите внимание, что я не слишком знаком со всей этой концепцией, но недавно немного поэкспериментировал с ней и кратко описал, как вы могли бы это реализовать.

Я приветствую тех, кто более опытен в многопоточности, чтобы исправить этот пост или предоставить дополнительную информацию в комментариях, чтобы помочь улучшить этот ответ.

Класс выполняемых задач

public class CompartmentalizationTask implements Runnable {

    private final ArrayList<Long> cc;
    private final long index;

    public CompartmentalizationTask(ArrayList<Long> list, long index) {

        this.cc = list;
        this.index = index;
    }

    @Override
    public void run() {
        Main.compartmentalize(cc, index);
    }
}

Основной класс

private static ExecutorService exeService = Executors.newCachedThreadPool();
private static List<Future> futureTasks = new ArrayList<>();

public static void tt4() throws ExecutionException, InterruptedException 
{
    long essir2 = 0;
    long essir3 = 0;

    ArrayList<Long> cc = new ArrayList<>();
    List<Long> range = new ArrayList<>();

    // break point is a method that returns list values, it was converted to
    // string because of some concatenations and would be converted back to long here
    for (String ari1 : Breakpoint()) {
        cc.add(Long.valueOf(ari1));
    }

    // the size of the List is huge about 1 trillion entries at the minimum
    long hy = cc.size() - 1;

    for (long k = 0; k < hy; k++) {
        futureTasks.add(Main.exeService.submit(new CompartmentalizationTask(cc, k)));
    }
    for (int i = 0; i < futureTasks.size(); i++) {
        futureTasks.get(i).get();
    }
    exeService.shutdown();
}

public static void compartmentalize(ArrayList<Long> cc, long index)
{
    long t1 = (long) cc.get((int) index);
    long t2 = (long) cc.get((int) (index + 1));

    // My main question: I am trying to iterate the entire list in a dynamic way
    // which would exclude repeated endpoints on each iteration.

    range = LongStream.rangeClosed(t1 + 1, t2)
            .boxed()
            .collect(Collectors.toList());

    for (long i : range) {
        // Hard is another method call on the iteration
        // complexcalc is a method as well

        essir2 = complexcalc((int) i, (int) Hard(i));
        essir3 += essir2;
    }
}
...