Bhavuk Garg Ответов: 1

Вычисление суммы в параллельном потоке работает медленнее, чем последовательная версия в java


Я узнал, что java предоставляет параллельные потоки для легкого использования нескольких потоков. Поэтому я попытался вычислить сумму массива как последовательно, используя цикл for, так и с помощью параллельного потока.
Но результат, который я получил, не удовлетворяет. Вот мой код=

public static void main(String[] args) {
		
		int arr[]=new int[10000];
		for(int i=0;i<10000;i++)	arr[i]=i;
		
		int sum=0;		//Sequential Sum
		long startTime=System.nanoTime();
		for(int i=0;i<10000;i++) sum+=arr[i];
		long seqTime=(System.nanoTime()-startTime);
		
		sum=0;		//Parallel Sum Using Stream
		startTime=System.nanoTime();
		sum=Arrays.stream(arr)
		.parallel()
		.sum();
		long parTime=(System.nanoTime()-startTime);
		System.out.println(parTime-seqTime);   // parallel - sequential
	}


Выход :
15802200


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

Что я уже пробовал:

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

1 Ответов

Рейтинг:
2

Richard MacCutchan

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

[редактировать]
Я только что обнаружил недостаток в вашем тесте, вы не сравниваете подобное с подобным. В первом случае вы просто складываете числа, чтобы получить сумму, что очень быстро на уровне процессора. Однако в вашем параллельном тесте вы используете Arrays.stream чтобы преобразовать массив в IntStream (Java Platform SE 8 )[^] объект, который добавляет значительные накладные расходы. Если вы измените первый код цикла на следующий это будет гораздо более корректный тест:

sum=Arrays.stream(arr).sum(); // a sequential summation

Поэтому когда я побежал то получил следующие результаты:
Sequential time: 18676400
  Parallel time: 12258900

Я провел еще несколько тестов, и параллельный прогон всегда был быстрее.
[/редактировать]


0x01AA

+5. также для последующего наблюдения и теста.

Richard MacCutchan

Спасибо. Удивительно, что вы можете узнать, просто прочитав документацию.