Mehrdimensionale Arrays in Java langsam?

Chr__Au

Mitglied
Hallo,

ich soll ein Programm schreiben in dem ich die These, dass Vektor- und Matrizenberechnung in Java langsam und nicht sinnvoll ist, beweisen.

Ich soll ein Vektor beliebiger Größe mit einem Array darzustellen und einen in dem die Werte in Objekt-Atribute gespeichert sind. Soweit alles klar.

Jetzt soll ich aber das gleiche mit Matrizen machen einmal mit einem Mehrdimensionalen-Array und einmal mit einem eindimensionalen Array + die Anzahl der Spalten als Atribut.

(
e00 e01 e02
e10 e11 e12
e20 e21 e22 )

Java:
new double [] {e00,e01,e02,e10,e11,e12,e20,e21,e22}


Zum Schluss soll ich eine Zeitmessung durchführen.

Leider benötigt die "Effizientere" Methode B (mit einem Array) in etwa 80% der Fälle mehr Zeit.

Kann es also sein, dass mehrdimensionale Arrays doch schneller sind, als dass ich immer schaue wann der nächste Zeilenumbruch sein muss?
[EDIT]Beispiel Ausgaben:
Code:
Vektor v1 5866
Vektor v2 2444
[14.0, 32.0, 50.0]
Matrix v1 27864
[6.0, 6.0, 6.0]
Matrix v1 44484

Vektor v1 5377
Vektor v2 1955
[14.0, 32.0, 50.0]
Matrix v1 25908
[6.0, 6.0, 6.0]
Matrix v1 29331

Vektor v1 5866
Vektor v2 2933
[14.0, 32.0, 50.0]
Matrix v1 26397
[6.0, 6.0, 6.0]
Matrix v1 23465
[/EDIT]
 
Zuletzt bearbeitet:
B

Beni

Gast
Kommt auf deinen Code an...

Aber wenn das in der JVM ähnlich wie bei C/C++ abläuft, wundert es mich nicht sehr, dass der 2d-array schneller sein kann.
2d array: array[x][y] wird zu einer Pointer-operation die etwa so aussieht "(array + size<int> * x) + size<int> * y", da size<int> etwas wie 4 oder 8 ist, kann natürlich das effiziente bit-shifting verwendet werden.
1d array: array[x][y] wird zu etwas wie "array + x + y * sizeOfOneRow". Nur "y * sizeOfOneRow" ist eine echte Multiplikation, also verhältnismässig ineffizient.
 

Chr__Au

Mitglied
okay, ka.

Vielleicht habe ich auch mist bei der Matrix-Vektor-Multiplikation gemacht. Für die Zuweisung habe ich 3 Methodenaufrufe:

numColumn -> soll die anzahl der Spalten aufnehmen
MathFactory.createVector -> wurde vom Prof so gewünscht
setVector -> erwartet einen index und einen Wert
getVector -> liefert einen double an der index pos zurück
matrix -> ist das eindimensionale Array welches eine Matrix simulieren soll.

Java:
public Vector multi(Vector vector) {
		Vector result = MathFactory.createVector(matrix.length / numColumn);
		for (int i = 0; i < matrix.length/numColumn; i++) {
			for (int k = 0; k < numColumn; k++) {
				result.setVector(i, result.getVector(i)
						+ matrix[numColumn * i + k] * vector.getVector(k));
			}
		}
		return result;
	}
 
Zuletzt bearbeitet:

Chr__Au

Mitglied
Also ich habe nur die Berechnung (mat_.multi(vector).g... und nicht das inizielisieren ... zwischen den Zeitmessungen, damit es auch wirklich keine unnötigen Verzögerungen gibt.

Java:
double[] tmpd1;
		long t1 = System.nanoTime();
		tmpd1 = mat1.multi(vector).getVector();
		long t2 = System.nanoTime();
		System.out.println(Arrays.toString(tmpd1));
		
		

		System.out.println("Matrix v1 " + (t2 - t1));

		double[] tmpd2;
		long t3 = System.nanoTime();
		tmpd2 = mat2.multi(vector).getVector();
		long t4 = System.nanoTime();
		System.out.println(Arrays.toString(tmpd2));

		System.out.println("Matrix v2 " + (t4 - t3));

Ich denke mal das bringt jetzt hier aber nichts mehr, ich frage einfach nächste Woche meinen Prof. Vielleicht sollte das ja auch gerade passieren.

Kein 3D einfach nur die Berechnung.
 
Zuletzt bearbeitet:

Ark

Top Contributor
Sehe ich das richtig, dass mit Vector hier nicht
Code:
java.util.Vector
gemeint ist?

Ist das eine Aufgabe vom Prof? Wenn ja:
ich soll ein Programm schreiben in dem ich die These, dass Vektor- und Matrizenberechnung in Java langsam und nicht sinnvoll ist, beweisen.
MathFactory.createVector -> wurde vom Prof so gewünscht
Wie geil ist das denn?! :lol:

[EDIT]Nur speziell "Matrix mal (eindimensionaler) Vektor", oder allgemein "Matrix mal Matrix"?[/EDIT]
Ark
 
Zuletzt bearbeitet:

Chr__Au

Mitglied
Also es soll eine Matrix Vektor multiplikation sein. Matrix * Vektor = Vektor

Die Factory soll eine möglichkeit bieten, entweder ein Vektor A (mit Array als Speicher) oder B mit (Atributen als Speicher, nur für 2dim Vektoren).

sowie Matrizen mit einem double[][] als Speicher und einmal mit double[] als speicher und zusätzlichem Spalten Atribut.

Bei der Multiplikation soll darauf geachtet werden, dass der Ergebnisvektor über die Fabrik erzeugt wird. Somit muss ich ja result mit createVektor anlegen.

Alle VectorKlassen sind von mir selbst geschrieben.
Java:
package chrau.prog2.exercises.set4;

public interface Vector {


	double[] sum(Vector secondAddend) throws ArithmeticException;

	
	double[] sub(Vector subtrahend) throws ArithmeticException;


	double[] ScalarMulti(double scalar);

	
	void setVector(double... element) throws IllegalArgumentException;


	double getVector(int index) throws IndexOutOfBoundsException;

	
	double[] getVector();

	
	void setVector(int index, double newValue) throws IndexOutOfBoundsException;

}


Aber allgemein ist meine Frage ja was ist schneller in Java, eine Matrix in einem mehrdimensionalen Array oder die Implementierung wie sie angeblich in C und C++ (kann ich leider beides nicht) ist:

(
e00 e01 e02
e10 e11 e12
e20 e21 e22 )


Java:
new double [] {e00,e01,e02,e10,e11,e12,e20,e21,e22}
 

Marco13

Top Contributor
Erstmal vorneweg: Die Zeitmessungen sind so vollkommen unsinning. Die Zeit, die zum Ausführen so einer kleinen Matrix-Vektor-Multiplikation benötigt wird, ist ggf. geringer, als die Auflösung, die der Timer für die Zeitmessung hat. "NanoTime" liefert zwar Zeiten in Nanosekunden, kann aber NICHT Nanosekunden-Genau messen - dafür müßtest du mal in der Physikalisch-Technischen Bundesanstalt in Braunschweig nachfragen - die mit der Atomuhr :D (In einer Nanosekunde bewegt sich ein Lichtstrahl ca. 30cm weit...)

Man müßte in diesem Fall also größere Matrizen verwenden. Da auch noch der JIT eine Rolle spielt, sollte die fragliche Methode außerdem eigentlich mehrere tausend mal aufgerufen werden, bis man verläßliche Ergebnisse bekommt. Ein Muster, mit dem man solchen "Microbenchmarks" wenigstens einen Hauch Aussagekraft geben kann, ist
Java:
long t0 = 0;
long t1 = 1;
int runs = 10;
for (int r=0; r<runs; r++)
{
    for (int size=100; size<=10000; size*=10)
    {
        Data data = createInputData();

        t0 = System.nanoTime();
        Result result0 = runMethod0(data);
        t1 = System.nanoTime();
        System.out.println("Result0 "+result0+" time "+((t1-t0)*1e-6)+" ms");

        t0 = System.nanoTime();
        Result result1 = runMethod1(data);
        t1 = System.nanoTime();
        System.out.println("Result1 "+result1+" time "+((t1-t0)*1e-6)+" ms");
    }
}

Also mehrmals beide Verfahren abwechselnd mit steigenden Eingabegrößen laufen lassen (und die Ergebnisse in einer Ausgabe verwenden, damit's nicht wegoptimiert werden kann). Ein bißchen mehr steht dazu in AngelikaLanger.com - Java Performance - Micro-Benchmarking - Angelika Langer Training/Consulting

Es wäre gut, wenn du genau beschreiben würdest, was vorgegeben ist, und was du selbst machen sollst. (Und wenn das Interface so vorgegeben war... :autsch: .. naja, war's wohl nicht)

Zur eigentlichen Frage: Ja, in C/C++ verwendet man tendenziell eher 1D-Arrays - auch für 2D-Matrizen. Der Grund dafür ist, dass ein dymamisch allokierter 2D-Array in C/C++ ein ziemlicher Krampf ist, weil man alle Zeilen einzeln allokieren und am Ende auch wieder einzeln löschen muss.

Der mögliche Geschwindigkeitsunterschied bei beiden Darstellungsweisen in Java kann aber viele Gründe haben. Ich bin da selbst mal drüber gestolpert: Der Thread http://www.java-forum.org/allgemein...nfluss-caching-performance-grosse-arrays.html könnte für dich in mehrerer Hinsicht interessant sein.
 

Ark

Top Contributor
@Marco13: Jaja, das berühmte Seitenflattern … (oder sollte man eher Cacheflattern sagen?) ;) https://en.wikipedia.org/wiki/Thrashing_(computer_science)

10000 Aufrufe sollten es schon mindestens sein: Stas's blog: The most complete list of -XX options for Java JVM Wobei das natürlich von der JVM-Implementierung abhängt. (Im OpenJDK scheint es diesen Parameter nicht zu geben, jedenfalls kommt bei mir immer nur eine Fehlermeldung, wenn ich ihn zu verwenden versuche.)

Meinen Messungen zufolge kann ich mit
Code:
System.nanoTime()
im Mittel nur eine Differenz von knapp 57 Nanosekunden erfassen. In der Zeit ist also das Licht 17 Meter weiter … :reflect: Bei solchen Zahlen wird einem irgendwie anders. :D

Zur eigentlichen Frage: Ja, in C/C++ verwendet man tendenziell eher 1D-Arrays - auch für 2D-Matrizen. Der Grund dafür ist, dass ein dymamisch allokierter 2D-Array in C/C++ ein ziemlicher Krampf ist, weil man alle Zeilen einzeln allokieren und am Ende auch wieder einzeln löschen muss.
Es gibt auch Performancegründe, und wahrscheinlich auch deshalb verwendet ein BufferedImage intern eindimensionale Arrays: Zweidimensionale Arrays werden (zumindest in Java) intern als Arrays von Arrays umgesetzt. Jedes dieser Arrays kann prinzipiell irgendwo auf dem Heap landen. Die räumliche Lokalität ist damit sehr wahrscheinlich nicht mehr sichergestellt. Folge: Die CPU-Caches haben schneller ein Problem damit, es kommt eher zu Cache-Misses und/oder Cache-Lines können nicht in vollem Maße benutzt werden.

Hab' mal gerade aus Jux und Tollerei was zusammengehackt:
Java:
	public static final void mulMatrixVector(final double[] matrix, final double[] vector, final double[] result){
		int mi = 0;
		for(int ri = 0; ri < result.length; ri++){
			double tmp = 0.0;
			for(int vi = 0; vi < vector.length; vi++){
				tmp += matrix[mi++] * vector[vi];
			}
			result[ri] = tmp;
		}
	}
Für Matrix×Vektor braucht man, wie man sieht, gar keine Information darüber, wie "breit" oder "hoch" die Matrix ist, da sich das alles durch die Dimensionen der beiden Vektoren (eingegebener Vektor und Zielvektor) ergibt. Für große Matrizen gibt es ganz andere Verfahren, und bei kleinen Matrizen fester Größe (ich nehme mal an, es geht hauptsächlich um 3×3-Matrizen) könnte man entsprechende Vereinfachungen/Spezialisierungen vornehmen.

Auch wenn ich den Ausgang des Experimentes noch nicht kenne: Ich vermute ebenfalls, dass da jemand einfach keine Ahnung hat, wie man richtig misst. ;)

Ark

[EDIT]Ich habe mir mal vor einiger Zeit einen Testrahmen für solche Zwecke geschrieben. Vielleicht sollte ich ihn mal ins Forum stellen. *überleg*[/EDIT]
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
N mehrdimensionale arrays Java Basics - Anfänger-Themen 12
J Mehrdimensionale Arrays Java Basics - Anfänger-Themen 2
melaniemueller Lagerverwaltung erstellen - mehrdimensionale Arrays Java Basics - Anfänger-Themen 62
J Methoden Mehrdimensionale Arrays übereinander legen Java Basics - Anfänger-Themen 5
F Mehrdimensionale Arrays Java Basics - Anfänger-Themen 12
G Mehrdimensionale Arrays Java Basics - Anfänger-Themen 17
T Mehrdimensionale Arrays mit geschachtelter for-Schleife initialisieren Java Basics - Anfänger-Themen 14
L mehrdimensionale arrays ich verzweifle so langsam... Java Basics - Anfänger-Themen 9
D Mehrdimensionale Arrays Sortieren Java Basics - Anfänger-Themen 5
T Mehrdimensionale Arrays Java Basics - Anfänger-Themen 4
B mehrdimensionale arrays Java Basics - Anfänger-Themen 4
B mehrdimensionale Arrays Java Basics - Anfänger-Themen 5
J eclipse, mehrdimensionale arrays, hilfsmethoden Java Basics - Anfänger-Themen 3
S arraycopy für mehrdimensionale Arrays? Java Basics - Anfänger-Themen 8
B Mehrdimensionale Arrays Java Basics - Anfänger-Themen 4
T mehrdimensionale arrays Java Basics - Anfänger-Themen 8
H Mehrdimensionale Arrays vergleichen Java Basics - Anfänger-Themen 6
G Zwei mehrdimensionale Arrays multiplizieren Java Basics - Anfänger-Themen 9
J Mehrdimensionale Arrays inhaltlich vergleichen. Java Basics - Anfänger-Themen 3
D mehrdimensionale nicht-rechteckige Arrays Java Basics - Anfänger-Themen 2
T Mehrdimensionale Array Java Basics - Anfänger-Themen 2
putinator Mehrdimensionale Array addieren Java Basics - Anfänger-Themen 10
D 2 mehrdimensionale Matrix einlesen Java Basics - Anfänger-Themen 2
T .add(E) für mehrdimensionale Vectoren Java Basics - Anfänger-Themen 5
H mehrdimensionale Datenstruktur erfassen Java Basics - Anfänger-Themen 10
L Mehrdimensionale Array Java Basics - Anfänger-Themen 4
A Mehrdimensionale Felder Java Basics - Anfänger-Themen 18
D Mehrdimensionale ArrayList - Zugriff über return Java Basics - Anfänger-Themen 2
B Mehrdimensionale Array Problem Java Basics - Anfänger-Themen 12
J Mehrdimensionale Liste erstellen ohne Array Java Basics - Anfänger-Themen 14
V Mehrdimensionale Collection? Java Basics - Anfänger-Themen 4
J Mehrdimensionale Array kopieren Java Basics - Anfänger-Themen 6
G Mehrdimensionale ArrayList erstellen Java Basics - Anfänger-Themen 7
D mehrdimensionale ArrayList ? Java Basics - Anfänger-Themen 14
M Länge eines Arrays als Variable speichern möglich? Java Basics - Anfänger-Themen 14
R Liste und Arrays Java Basics - Anfänger-Themen 12
E Arrays in einer ArrayList miteinander vergleichen Java Basics - Anfänger-Themen 12
Kingdako Wie löse ich eine Mathematische Formel mit Arrays und Schleifen? Java Basics - Anfänger-Themen 32
D Wie kann man in Java nach Arrays auf Duplikate prüfen Java Basics - Anfänger-Themen 12
S Hilfe bei Praktischen Aufgaben von Arrays Java Basics - Anfänger-Themen 39
T Objekte mit arrays erstellen Java Basics - Anfänger-Themen 6
M Problem bei verschachtelter for-Schleife bei zweidimensionalen Arrays Java Basics - Anfänger-Themen 3
pc pc pc pc pc letztes Element eines Arrays n Java Basics - Anfänger-Themen 3
M Arrays Java Basics - Anfänger-Themen 3
Ostkreuz Wert von Arrays summieren Java Basics - Anfänger-Themen 1
Ostkreuz Summieren von Arrays Java Basics - Anfänger-Themen 4
javaBoon86 Arrays 2 Dimension Werte ausgeben Java Basics - Anfänger-Themen 15
paulen1 Best Practice "Unchecked Assignment" Warnung beim erstellen eines 2D Arrays of Arraylists Java Basics - Anfänger-Themen 2
B bei 2 Arrays Anzahl gleicher Elemente vergleichen? Java Basics - Anfänger-Themen 49
JustAProgrammer Ein Dreieck mit Arrays erstellen Java Basics - Anfänger-Themen 2
TheSepp Nur Arrays ausgeben, die Werte zugewiesen haben. Java Basics - Anfänger-Themen 4
volcanos Addition -> List<Integer> mit Arrays.asList() versus List<Integer>ArrayList<>() Java Basics - Anfänger-Themen 14
ArrayList mit unbekannter Menge an Arrays die Arrays vergleichen Java Basics - Anfänger-Themen 9
D Arrays an replaceAll-Methode übergeben Java Basics - Anfänger-Themen 12
rosima26 Geordnete Arrays ausgeben Java Basics - Anfänger-Themen 31
D Inhalt eines Arrays ausgeben Java Basics - Anfänger-Themen 7
A Jedes zweite Element eines Arrays entfernen Java Basics - Anfänger-Themen 30
C Zwei Arrays addieren und ausgeben Java Basics - Anfänger-Themen 3
E Zinsrechnung mithilfe von Arrays Java Basics - Anfänger-Themen 12
LePetitChat1 Arrays - NullPointerException? Java Basics - Anfänger-Themen 14
H Arrays: Größten Zahlen Unterschied herausfinden Java Basics - Anfänger-Themen 20
H Arrays befüllen Java Basics - Anfänger-Themen 43
C60 Methoden Main-Methode erkennt meine Arrays nicht. Java Basics - Anfänger-Themen 7
D Arrays Java Basics - Anfänger-Themen 9
C Java Arrays - Ausgabe in Methode Java Basics - Anfänger-Themen 12
R While-Loop der die Einträge eines Arrays in umgekehrter Reihenfolge anzeigt Java Basics - Anfänger-Themen 3
N Arrays Java Basics - Anfänger-Themen 5
W n verschiedene Arrays zufällig ausgeben - mit der Random-Klasse? Java Basics - Anfänger-Themen 8
U zwei 2D arrays auf gleich sein überprüfen Java Basics - Anfänger-Themen 14
C initialisieren eines arrays richtiger Größe und mit geeignetem Datentyp Java Basics - Anfänger-Themen 26
Bademeister007 Elemente aus zwei verschiedenen Arrays miteinander vergleichen und gegeben falls entfernen Java Basics - Anfänger-Themen 14
A Arrays aufsummieren Java Basics - Anfänger-Themen 11
C Wie 2 Arrays zusammenfügen und sortieren? Java Basics - Anfänger-Themen 11
S Arrays aneinanderketten Java Basics - Anfänger-Themen 20
Sinan Arrays auflisten ohne Wiederholung Java Basics - Anfänger-Themen 28
D Hilfe beim Erzeugen eines Arrays NullPointerException wird ausgelöst Java Basics - Anfänger-Themen 11
R Werte und Reihenfolge in 2d Arrays vergleichen Java Basics - Anfänger-Themen 5
D Verschlüsslungsaufgabe / Arrays Java Basics - Anfänger-Themen 6
L Methode für Zweidimensionale Arrays Java Basics - Anfänger-Themen 4
L Methode zum invertieren eines Arrays Java Basics - Anfänger-Themen 7
S zweidimensionale char arrays Java Basics - Anfänger-Themen 14
D Verwirrung bei Streams aus primitiven Arrays Java Basics - Anfänger-Themen 2
P Arrays mit verschiedenen Längen miteinander dividieren. Java Basics - Anfänger-Themen 1
P Wie kann ich die Zahlen dieses Arrays dividieren? Java Basics - Anfänger-Themen 2
N 2D Arrays jedes xy vergleichen Java Basics - Anfänger-Themen 7
J Traveling Salesman Problem [Arrays] Java Basics - Anfänger-Themen 9
M Arrays mit mehreren Werten über JOptionPane initialisieren Java Basics - Anfänger-Themen 12
Kawastori Größe eines Arrays bestimmen Java Basics - Anfänger-Themen 13
Zeppi Arrays[i] Java Basics - Anfänger-Themen 7
Lena_2611 Vergleich von Array1 Index mit Array2 Wert und erzeugen eines neues Arrays Java Basics - Anfänger-Themen 8
J B-Sprache mit Arrays ausführen Java Basics - Anfänger-Themen 18
A Teilarrays eines 2D-Arrays sortieren Java Basics - Anfänger-Themen 4
C Arrays - deklarieren, initialisieren? Ist das ein Objekt? Java Basics - Anfänger-Themen 3
K Sudoku mit 2D Arrays Java Basics - Anfänger-Themen 19
T Vertikales Histogramm mit Arrays Java Basics - Anfänger-Themen 3
JD_1998 Arrays einlesen, zwischenspeichern und wieder ausgeben Java Basics - Anfänger-Themen 8
Z Kein überprüfen des gesamten Arrays möglich.(Viergewinnt Spiel) Java Basics - Anfänger-Themen 6
F Arrays: Mathematische Funktion Java Basics - Anfänger-Themen 19
mihe7 Von Datentypen und (mehrdimensionalen) Arrays Java Basics - Anfänger-Themen 4
A Teilen eines Arrays Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben