MergeSort - Threads in Anwendung bremsen alles!

Mujahiddin

Top Contributor
Einen guten Tag...
Ich habe heute den Sortieralgorithmus MergeSort auf Zahlen geschrieben.
Dieser arbeitet mit Vectoren, die zuerst in der Rekursion aufgeteilt werden, sortiert zusammengefasst werden, bis schließlich das angeforderte sortiert ist...
Alles klappt wunderbar... Ich dachte mir aber, wenn ich Threads laufen lasse, womit ich diese 'Unteraufteilung / Sortierung', die nicht voneinander abhängen, gleichzeitig von statten bringe, wäre die Aktion viel schneller fertig, und man müsste nicht immer alles Schritt für Schritt machen...
Zu meiner Überraschung stellte sich genau das Gegenteil heraus: Mit Threads dauert alles 15 mal so lange... (Bei ca. 4050 Einträgen: ~680-800 Millisekunden, Threadlos: ~30 Millisekunden)
Den Sortiervorgang selber, also zwei sortierte Listen in eine sortierte Liste einzufügen, ist bei beiden Vorgängen / Klassen gleich.
Der Unterschied liegt nur darin, dass beim einen die Unterteilung und der Splittvorgang im Thread ausgeführt wird, der, wenn nötig, auf einen anderen Thread wartet, bis dieser fertig ist, auch wenn nötig.

Hier mal ein Quellcode:
Java:
public class Algorithm 
{
	Vector<Integer> toMerge = new Vector<Integer>();
	public Algorithm()
	{
		toMerge.addElement(new Integer(3));
		toMerge.addElement(new Integer(2));
		toMerge.addElement(new Integer(44));
		toMerge.addElement(new Integer(5));
		toMerge.addElement(new Integer(4));
		[...]
	}
	public Vector<Integer> sort(Vector<Integer> firstSorted, Vector<Integer> secondSorted)
	{
		int fusionedLength = firstSorted.size() + secondSorted.size();
		Vector<Integer> fusioned = new Vector<Integer>();
		for(int i=0; i<fusionedLength; i++)
			if(secondSorted.size() == 0 && firstSorted.size() > 0 || firstSorted.size() > 0 && firstSorted.get(0) <= secondSorted.get(0))
				fusioned.addElement(firstSorted.remove(0));
			else
				fusioned.addElement(secondSorted.remove(0));
		return fusioned;
	}
<< Dieser Auszug is bei beiden Klassen gleich...

Klasse mit Threads:
Java:
	public Algorithm()
	{
		[...]
		toMerge.addElement(new Integer(10));
		System.out.println(toMerge.size());
		long start = new Date().getTime();
		System.out.println(start);
		Thread sortThread = new Thread(new SortThread(toMerge, this));
		sortThread.start();
		try 
		{
			sortThread.join();
		} catch (InterruptedException e) 
		{
			e.printStackTrace();
		}
		System.out.println(toMerge);
		long end = new Date().getTime();
		System.out.println(end);
		long duration = end-start;
		System.out.println("Dauer: " + duration);
	}
	
	
	
	class SortThread implements Runnable
	{
		Vector<Integer> toSort = null;
		Vector<Integer> firstPart = null;
		Vector<Integer> secondPart = null;
		SortThread starterThread = null;
		Algorithm starter = null;
		boolean first = false;
		SortThread(Vector<Integer> toSort, SortThread starterThread, boolean first)
		{
			this.first = first;
			this.toSort = toSort;
			this.starterThread = starterThread;
		}
		SortThread(Vector<Integer> toSort, Algorithm starterThread)
		{
			this.toSort = toSort;
			this.starter = starterThread;
		}
		public void run()
		{
			int toSortLength = toSort.size();
			firstPart = new Vector<Integer>();
			secondPart = new Vector<Integer>();
			for(int i=0; i<toSortLength; i++)
				if(i%2 == 0)
					firstPart.addElement(toSort.get(i));
				else
					secondPart.addElement(toSort.get(i));
			Thread firstPartThread = null;
			int firstPartLength = firstPart.size();
			if(firstPartLength > 1)
			{
				firstPartThread = new Thread(new SortThread(firstPart, this, true));
				firstPartThread.start();
			}
			Thread secondPartThread = null;
			int secondPartLength = secondPart.size();
			if(secondPartLength > 1)
			{
				secondPartThread = new Thread(new SortThread(secondPart, this, false));
				secondPartThread.start();
			}
			try
			{
				if(firstPartThread != null)
					firstPartThread.join();
				if(secondPartThread != null)
					secondPartThread.join();
			} catch(InterruptedException e)
			{
				e.printStackTrace();
			}
			toSort = sort(firstPart, secondPart);
			if(starterThread != null)
				if(first)
					starterThread.firstPart = toSort;
				else
					starterThread.secondPart = toSort;
			else
				starter.toMerge = toSort;
		}
	}

Klasse ohne Threads (wesentlich kürzer):
Java:
	public Algorithm()
	{
		[...]
		toMerge.addElement(new Integer(10));
		long start = new Date().getTime();
		System.out.println(start);
		toMerge = merge(toMerge);
		System.out.println(toMerge);
		long end = new Date().getTime();
		System.out.println(end);
		long duration = end-start;
		System.out.println("Dauer: " + duration);
	}


	public Vector<Integer> merge(Vector<Integer> toSort)
	{
		int toSortLength = toSort.size();
		Vector<Integer> firstPart = new Vector<Integer>();
		Vector<Integer> secondPart = new Vector<Integer>();
		for(int i=0; i<toSortLength; i++)
			if(i%2 == 0)
				firstPart.addElement(toSort.get(i));
			else
				secondPart.addElement(toSort.get(i));
		int firstPartLength = firstPart.size();
		if(firstPartLength > 1)
			firstPart = merge(firstPart);
		int secondPartLength = secondPart.size();
		if(secondPartLength > 1)
			secondPart = merge(secondPart);
		Vector<Integer> sorted = new Vector<Integer>();
		sorted = sort(firstPart, secondPart);
		return sorted;
	}

Habe ich vielleicht einen Fehler im Quellcode, der alles umsonst bremst? Oder liegt das daran, dass einen Thread zu starten enorm viel mehr Zeit kostet, als einfach alles nacheinander zu machen?

Danke für euren Tipp!

Muja
 

andiv

Bekanntes Mitglied
MergeSort ist ein Easy-Split/Hard-Join-Algorithmus, d.h. das Aufteilen der Ausgangsliste auf zwei Teillisten geht schnell während das Zusammenfügen zur sortierten Liste eher aufwändig ist.

Wenn du hier optimieren wilst, dann musst du eher beim zweiten Teil ansetzen.

Dementsprechend sollte auch klar sein, das der Einsatz mehrerer Threads zum Aufteilen kaum Nutzen bringt.

Dass Threads das ganze sogar langsamer machen lässt sich damit erklären, dass das Erstellen eines Threads und insbesondere die Synchronisierung relativ teuer sind.
 

Mujahiddin

Top Contributor
Okay, das verstehe ich ja, aber wie sollte ich, deiner Meinung nach, den Algorithmus (den Join Algorithmus) optimieren? Wenn ich mir meinen Code anschaue, dann kann ich mir gar nichts Kürzeres vorstellen.. Und wie sollte ich da Threads anwenden? Synchronität wäre hier doch schwachsinnig, da man sowieso immer auf das nächste Objekt warten muss... Findest du nicht auch?
 

Schandro

Top Contributor
vllt. wäre es schneller, intern mit Arrays statt Vectoren-Objekten zu arbeiten!? Instanzen kosten schließlich einiges.
 
Zuletzt bearbeitet:
S

SlaterB

Gast
ich schau mir nachher noch den Code an, falls da was zu tun ist,
vorher bisschen blahblah

Ich dachte mir aber, wenn ich Threads laufen lasse, womit ich diese 'Unteraufteilung / Sortierung', die nicht voneinander abhängen, gleichzeitig von statten bringe, wäre die Aktion viel schneller fertig, und man müsste nicht immer alles Schritt für Schritt machen...
Zu meiner Überraschung stellte sich genau das Gegenteil heraus: Mit Threads dauert alles 15 mal so lange...

Threads sind unendlich langsam und können von sich aus nichts besser, jedenfalls nicht Richtung Geschwindigkeit wenn nicht gerade wirklich mehrere CPUs gleichzeitig genutzt werden können,
klassischerweise hat man ja eher eine CPU und die Threads müssen sich abwechseln,
die Erstellung und das Hin- und Herschalten kann Ewigkeiten dauern,
der Vorteil der Threads liegt in ersten Linie in der Möglichkeit zur natürlichen Organisation mehrere Vorgänge

zwei entfernte Analogien:
1.
System.out.println("Test") vs eine GUI mit Textfeld und darin "Test", letzteres bringt den User auch nicht viel mehr Infos, dauert 1000fach länger, verbraucht MB an zusätzlichen Speicher,
dafür hat man Eventhandling und andere komfortable Möglichkeiten

2.
fünf Assembler/ Maschensprachen-Befehle vs. ein einfaches Java-Programm mit System.out.println("Test"),
letztes ist zwar viel schneller als ne GUI, für sich aber auch 1000fach langsamer als was ein PC wirklich könnte mit seinen GHz an Arbeitsgeschwindigkeit,
die Hochsprache mit ihren aufwendigen Interpretationssystem, Hintergrundthreads, 1 sec + 10 MB allein zum Starten nimmt man in Kauf,
weil man dabei auch wieder jede Menge Komfort erhält, einfache Programmierbefehle, Speichermanagement, direkt verfügbare Input + Output usw.



edit:
zum Code: mehr als Entfernen der Threads ist dabei wohl als wichtigster Schritt nicht zu tun,
wenn überhaupt, dann kannst du überlegen, bei sehr vielen Elementen in den obersten Schichten zu trennen, so dass vielleicht 2, 4 oder 8 laufen, die jeweils paar tausend bis Millionen sortieren,
aber auf den unteren Ebenen neue Threads, das macht im besonderen Maße keinen Sinn
 
Zuletzt bearbeitet von einem Moderator:
Ähnliche Java Themen
  Titel Forum Antworten Datum
L Mergesort (aber anders) Java Basics - Anfänger-Themen 2
KogoroMori21 MergeSort Algorithmus Java Basics - Anfänger-Themen 2
O Rekursion Mergesort Java Basics - Anfänger-Themen 18
E Methoden 2 Arrays sortieren (MergeSort) Java Basics - Anfänger-Themen 3
H Mergesort aufwand berechen Java Basics - Anfänger-Themen 5
I MergeSort iterativ mit Stacks Java Basics - Anfänger-Themen 13
L Methoden Mergesort methode Java Basics - Anfänger-Themen 4
K MergeSort Stackoverflow Java Basics - Anfänger-Themen 5
K Mergesort Fehler in der Implementierung Java Basics - Anfänger-Themen 2
T MergeSort rekursiv programmieren Java Basics - Anfänger-Themen 8
A Rekursion (anhand von Mergesort) nachvollziehen Java Basics - Anfänger-Themen 4
M Erklärung Code Mergesort Bitte Java Basics - Anfänger-Themen 3
A Probleme mit MergeSort Generische Liste Java Basics - Anfänger-Themen 0
M Mergesort Aufgabe große Probleme Java Basics - Anfänger-Themen 9
P Mergesort Probleme Java Basics - Anfänger-Themen 4
I Mergesort mit ArrayList Java Basics - Anfänger-Themen 4
C Mergesort Java Basics - Anfänger-Themen 4
H MergeSort (für Anfänger ) Java Basics - Anfänger-Themen 9
N MergeSort Java Basics - Anfänger-Themen 8
M MergeSort - Zahlen verschwinden Java Basics - Anfänger-Themen 2
P MergeSort mit Liste Java Basics - Anfänger-Themen 4
M MergeSort rekursiv Java Basics - Anfänger-Themen 2
B Methoden Natural Mergesort Java Basics - Anfänger-Themen 2
P Mergesort || 2 SetLists mischen Java Basics - Anfänger-Themen 2
P Mergesort (zyklische Liste) Java Basics - Anfänger-Themen 2
X eigener Mergesort auf generischen Typen mit Comparator Java Basics - Anfänger-Themen 6
N MergeSort mit Liste Java Basics - Anfänger-Themen 8
P Probleme bei codierung von MergeSort Java Basics - Anfänger-Themen 4
Houly Mergesort Java Basics - Anfänger-Themen 4
M Mergesort Java Basics - Anfänger-Themen 11
C MergeSort Problem Java Basics - Anfänger-Themen 5
F MergeSort iterativ mit Hilfe von Stack Java Basics - Anfänger-Themen 5
B mergesort/rekursion Java Basics - Anfänger-Themen 9
H Nutzt Eclipse alle CPU-Threads beim Ausführen von Java-Programmen? Java Basics - Anfänger-Themen 4
C Threads und Swing Java Basics - Anfänger-Themen 9
berserkerdq2 Wo finde ich in der Java Api die Notation zu Threads bezüglich Synchronized? Java Basics - Anfänger-Themen 14
berserkerdq2 Findet eine parallele Verarbeitung in Java bei Threads erst statt, wenn man die Methoden auch synchronized? Und wie sieht bei Conditions aus? Java Basics - Anfänger-Themen 8
B Monitor als Schranke von Threads Java Basics - Anfänger-Themen 20
W Threads Alphabet Java Basics - Anfänger-Themen 20
H Threads Anfänger Java Basics - Anfänger-Themen 17
1 Threads parallel laufen Java Basics - Anfänger-Themen 11
B Threads Problem mit mehreren Threads Java Basics - Anfänger-Themen 38
M Threads Java Basics - Anfänger-Themen 12
L Threads Synchronisierung zwischen threads Java Basics - Anfänger-Themen 4
M Threads Java Basics - Anfänger-Themen 2
A Threads Java Basics - Anfänger-Themen 9
A Threads Java Basics - Anfänger-Themen 13
A Threads und .join Java Basics - Anfänger-Themen 14
W Threads starten Java Basics - Anfänger-Themen 2
X Threads Zwei Threads, aber doppelte Ausgabe verhindern (synchronized) Java Basics - Anfänger-Themen 54
J Wieviele threads? Java Basics - Anfänger-Themen 9
J Problem bei seriellem Start von Threads Java Basics - Anfänger-Themen 11
O Threads Java Basics - Anfänger-Themen 2
L Buchungssystem und Threads Java Basics - Anfänger-Themen 2
O Threads - Synchronize(), join(), wait(), notify(), yield() Java Basics - Anfänger-Themen 6
L Klassen NFC Reader und JavaFx Problem -> threads? Java Basics - Anfänger-Themen 2
A Kommunikation zwischen nebenläufigen Threads Java Basics - Anfänger-Themen 4
S Gemeinsame Ressource und Mehrfachinstanziierung von Threads Java Basics - Anfänger-Themen 16
S Verklemmung Threads Java Basics - Anfänger-Themen 11
B Threads 2 Threads gleichzeitig laufen lassen Java Basics - Anfänger-Themen 1
M Threads Threads laufen sequenziell, statt gleichzeitig. Java Basics - Anfänger-Themen 9
M Threads run Methode Java Basics - Anfänger-Themen 4
javajoshi mehrere Threads: Methoden zentral unterbringen Java Basics - Anfänger-Themen 8
javajoshi Problem mit zwei Threads und Arrays (Runnable) Java Basics - Anfänger-Themen 12
L Threads Mit Threads JLabel ändern! Java Basics - Anfänger-Themen 2
K Matrixen berechnen nach Worker Master Paradigma mit Threads Java Basics - Anfänger-Themen 4
S Kleine Frage zu Threads Java Basics - Anfänger-Themen 3
M Mit 2 Threads eine Zahl hochzählen Java Basics - Anfänger-Themen 13
T Threads Synchronisieren Java Basics - Anfänger-Themen 6
D Frage Threads Java Basics - Anfänger-Themen 6
Z Threads Executor Framework - Aufgabe auf n Threads aufteilen Java Basics - Anfänger-Themen 10
Z Threads Threads - Zugriff auf Ressourcen ohne(Lock, Synchronized) Java Basics - Anfänger-Themen 2
kilopack15 Verständnisfrage zur Verwendung von notify() bei Threads Java Basics - Anfänger-Themen 2
kilopack15 Mehrere Threads in einer Klasse Java Basics - Anfänger-Themen 8
H Threads funktionieren nicht Java Basics - Anfänger-Themen 4
J Aufgabe(Threads) richtig verstanden/implementiert Java Basics - Anfänger-Themen 27
R Threads aufeinander warten lassen? Java Basics - Anfänger-Themen 10
T Threads Durch threads gestartete Prozesse killen Java Basics - Anfänger-Themen 2
J Threads Java Basics - Anfänger-Themen 38
D Alte Klausuraufgabe Threads Java Basics - Anfänger-Themen 10
A Threads Threads bestimmte Aufgaben zuweisen... Java Basics - Anfänger-Themen 3
R Threads in JavaFX Java Basics - Anfänger-Themen 3
E Threads Doppelte Threads beenden Java Basics - Anfänger-Themen 4
F Sicheres Zurückmelden aus Threads Java Basics - Anfänger-Themen 0
G Threads zum Thema Threads??? null Ahnung Java Basics - Anfänger-Themen 4
Q Threads Threads in Swing Anwendungen Java Basics - Anfänger-Themen 5
J ConcurrentCalculation Multi Threads in Java Java Basics - Anfänger-Themen 3
P Threads Trotz Threads wird nur 1 Prozessorkern ausgelastet Java Basics - Anfänger-Themen 7
M "restartable" threads Java Basics - Anfänger-Themen 11
M Threads - summieren Java Basics - Anfänger-Themen 13
W Klassen Variable einer anderen Klasse ändern (Threads) Java Basics - Anfänger-Themen 3
E Threads - Programm analysieren Java Basics - Anfänger-Themen 2
E join() bei zwei Threads Java Basics - Anfänger-Themen 2
T Threads Threads richtig synchronisieren Java Basics - Anfänger-Themen 3
D [Concurrency/Threads] Code Umsetzung Schriftlich Java Basics - Anfänger-Themen 2
D Threads Java Basics - Anfänger-Themen 4
M Threads nio Dateien kopieren, Threads und Gui Java Basics - Anfänger-Themen 0
N Verweise auf Variablen in verschiedenen Threads Java Basics - Anfänger-Themen 4
T Java-Threads Java Basics - Anfänger-Themen 0
G Moving Objects with Threads (implements Runnable) Java Basics - Anfänger-Themen 1

Ähnliche Java Themen

Neue Themen


Oben