Я реализовал многопоточную сортировку слиянием с помощью платформы Java ForkJoin и хотел собрать отзывы о ее правильности, эффективности и масштабируемости.
Вот моя реализация:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
public class CustomRecursiveTaskForArraysSorting extends RecursiveTask[*]> {
private static final int THRESHOLD = 2;
private final List workload;
public CustomRecursiveTaskForArraysSorting(List workload) {
if (workload == null) {
throw new IllegalArgumentException("Workload cannot be null");
}
this.workload = workload;
}
@Override
protected List compute() {
if (workload.size() > THRESHOLD) {
return ForkJoinTask.invokeAll(createSubtasks(workload))
.stream()
.map(ForkJoinTask::join)
.reduce(this::merge)
.orElseThrow();
} else {
return processing(workload);
}
}
private List createSubtasks(List workload) {
List subtasks = new ArrayList();
List firstHalf = workload.subList(0, workload.size() / 2);
List secondHalf = workload.subList(workload.size() / 2, workload.size());
subtasks.add(new CustomRecursiveTaskForArraysSorting(new ArrayList(firstHalf)));
subtasks.add(new CustomRecursiveTaskForArraysSorting(new ArrayList(secondHalf)));
return subtasks;
}
private List processing(List workload) {
Collections.sort(workload);
return workload;
}
private List merge(List a, List b) {
List merged = new ArrayList();
int i = 0, j = 0;
while (i < a.size() && j < b.size()) {
if (a.get(i) < b.get(j)) {
merged.add(a.get(i++));
} else {
merged.add(b.get(j++));
}
}
merged.addAll(a.subList(i, a.size()));
merged.addAll(b.subList(j, b.size()));
return merged;
}
}
Основные особенности:
Я использую RecursiveTask для рекурсивного разделения массива на более мелкие части. до тех пор, пока не будет достигнут пороговый размер, после чего массивы меньшего размера сортируются напрямую.
Функция слияния объединяет два отсортированных подмассива в один отсортированный массив.
Маленькие массивы сортируются с помощью Collections.sort()
Вопросы:
Есть ли какие-либо крайние случаи или узкие места в производительности, которые я мог упустить из виду?
Можно ли дополнительно оптимизировать эту реализацию для больших наборов данных или более высокого уровня параллелизма?
Насколько это сравнимо с ручным управлением потоками с точки зрения производительности и читабельности?
Я ценю любые конструктивные отзывы и предложения по улучшению реализации.
Я реализовал многопоточную сортировку слиянием с помощью платформы Java ForkJoin и хотел собрать отзывы о ее правильности, эффективности и масштабируемости. Вот моя реализация: [code]import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.RecursiveTask;
public class CustomRecursiveTaskForArraysSorting extends RecursiveTask[*]> { private static final int THRESHOLD = 2; private final List workload;
public CustomRecursiveTaskForArraysSorting(List workload) { if (workload == null) { throw new IllegalArgumentException("Workload cannot be null"); } this.workload = workload; }
private List createSubtasks(List workload) { List subtasks = new ArrayList(); List firstHalf = workload.subList(0, workload.size() / 2); List secondHalf = workload.subList(workload.size() / 2, workload.size()); subtasks.add(new CustomRecursiveTaskForArraysSorting(new ArrayList(firstHalf))); subtasks.add(new CustomRecursiveTaskForArraysSorting(new ArrayList(secondHalf))); return subtasks; }
private List processing(List workload) { Collections.sort(workload); return workload; }
private List merge(List a, List b) { List merged = new ArrayList(); int i = 0, j = 0; while (i < a.size() && j < b.size()) { if (a.get(i) < b.get(j)) { merged.add(a.get(i++)); } else { merged.add(b.get(j++)); } } merged.addAll(a.subList(i, a.size())); merged.addAll(b.subList(j, b.size())); return merged; } } [/code] [b]Основные особенности:[/b] [list] Я использую RecursiveTask для рекурсивного разделения массива на более мелкие части. до тех пор, пока не будет достигнут пороговый размер, после чего массивы меньшего размера сортируются напрямую. [*]Функция слияния объединяет два отсортированных подмассива в один отсортированный массив. [*]Маленькие массивы сортируются с помощью Collections.sort() [/list] [b]Вопросы[/b]: [list] [*]Есть ли какие-либо крайние случаи или узкие места в производительности, которые я мог упустить из виду? [*]Можно ли дополнительно оптимизировать эту реализацию для больших наборов данных или более высокого уровня параллелизма? [*] Насколько это сравнимо с ручным управлением потоками с точки зрения производительности и читабельности? [/list] Я ценю любые конструктивные отзывы и предложения по улучшению реализации.
В алгоритме сортировки слиянием мы используем рекурсию для левой и правой частей, массив делится рекурсивно до тех пор, пока размер подмассива не станет равным 1. После разделения подмассивов я узнал, что левый и правый подмассивы сортируются и...
Я пытаюсь изучить React, следуя приведенному ниже видео.
По какой-то причине внутри тега div ничего не печатается.
Можете ли вы сообщить мне, как это исправить.
Предоставление кода и песочница ниже.
Я отлаживал, используя консоль, но все равно...