Почему служба executor занимает больше времени, чем последовательная операция в Java 8? - PullRequest
2 голосов
/ 06 апреля 2019

В следующей программе я хочу отсортировать 4 разных массива параллельно, поэтому использовал executorService для создания FixedThreadPool с размером 4 (количество доступных процессоров). Я предполагаю, что это займет меньше времени по сравнению с последовательной операцией, но я вижу, что последовательная операция быстрее. Любая дальнейшая оптимизация нужна здесь?

Вот код:

public class ThreadFoolOptimumSize {

private static int data1[] = new int[10000];
private static int data2[] = new int[20000];
private static int data3[] = new int[10000];
private static int data4[] = new int[30000];

public static void main(String ars[]) {
    long startTime = System.currentTimeMillis();
    int processors_count = Runtime.getRuntime().availableProcessors();
    System.out.println(processors_count);
    Random random = new Random();
    data1 = random.ints(10000, 10, 10000).toArray();
    data2 = random.ints(20000, 10, 20000).toArray();
    data3 = random.ints(10000, 10, 10000).toArray();
    data4 = random.ints(30000, 10, 30000).toArray();

    ExecutorService executorService = Executors.newFixedThreadPool(processors_count);
    executorService.execute(new Runnable() {
        public void run() {
            Arrays.sort(data1);
            System.out.println("sorted data1:");
            System.out.println(Arrays.toString(data1));
        }
    });

    executorService.execute(new Runnable() {
        public void run() {
            Arrays.sort(data2);
            System.out.println("sorted data2:");
            System.out.println(Arrays.toString(data2));
        }
    });

    executorService.execute(new Runnable() {
        public void run() {
            Arrays.sort(data3);
            System.out.println("sorted data3:");
            System.out.println(Arrays.toString(data3));
        }
    });

    executorService.execute(new Runnable() {
        public void run() {
            Arrays.sort(data4);
            System.out.println("sorted data4:");
            System.out.println(Arrays.toString(data4));
        }
    });

    executorService.shutdown();

    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            long endTime = System.currentTimeMillis();
            System.out.println("Total:" + (endTime-startTime) + " ms");
        }
    });
}

}

1 Ответ

2 голосов
/ 07 апреля 2019

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

Увеличив еще один коэффициент в десять (так что размеры составляют порядка миллионов), я, наконец, заставляю Исполнителя работать быстрее.

Таким образом, ясно, сколько данных вам нужно обработать, в некоторых случаях не стоит использовать Executor. (Конечно, я прокомментировал распечатку отсортированных массивов).

Кроме того, добавьте, что использование разных размеров массивов делает разницу менее очевидной: в начале вы сортируете 4 массива параллельно, через 1/3 времени вы завершаете 2 сортировки, data1 и data3, и продолжаете обрабатывать две другие параллельно, data2 и data4, а последнюю треть времени вы обрабатываете в одном массиве, data4. Если вы сортируете идентичные массивы, выигрыш в скорости будет более очевидным.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...