2014-02-20 1 views
7

In meinem Programm habe ich ein großes (z. B. 100x100) Array von Strukturen, wobei jede Struktur eine angemessene Menge an Daten aufweist (z. B. 1000 Zahlen und einige andere Felder). Zum Beispiel:Wie man eine "Referenz" zu einer Struktur in Matlab macht?

for x = 100 : -1 : 1 
    for y = 100 : -1 : 1 
     database(y,x).data = rand(30); 
     database(y,x).name = sprintf('my %d %d', x, y); 
    end 
end 

Ich möchte eine Berechnung von 10-20 Zeilen Code mit meinen Daten tun; zum Beispiel:

for x = 10 : 90 
    for y = 10 : 90 
     for dx = -9 : 9 
      for dy = -9 : 9 
       result = result + database(y + dy, x + dx).data(1, 1); 
       result = result + 2 * database(y + dy, x + dx).data(1, 2) * database(y + dy, x + dx).data(2, 2); 
       ... % more stuff here 
      end 
     end 
    end 
end 

verweist Mein Code auf aktuelles Element der Datenbank als database(y + dy, x + dx). Um es kürzer zu machen, gebe es einen Namen zu (C++ würde es nennen „Referenz“):

temp = database(y + dy, x + dx); 
result = result + temp.data(1, 1); 
result = result + 2 * temp.data(1, 2) * temp.data(2, 2); 

Das ist mein Code macht viel kürzer und klarer. Dies ist jedoch auch viel langsamer und Profiling zeigt, dass die Zuweisung temp = ... 70% meiner Ausführungszeit dauert.

Also meine Annahme ist, dass Matlab Kopien den Inhalt des größeren Datenbankelements, meine Zeit zu essen. Ich denke Matlab sollte schlau genug sein, "Copy-on-Write" zu machen, das heißt, kopieren Sie das Zeug nur, wenn es später geändert wird. In meinem Fall passiert dies jedoch nicht - mein Code liest nur aus der Datenbank und ändert sie nicht.

Also, wie kann ich einen effizienten schreibgeschützten Verweis auf eine Struktur machen?

+0

+1 gute Frage - Ich würde gerne die Antwort darauf auch wissen. Jeder Ansatz, den ich ausprobiert habe (das Ausnutzen von Copy-on-Write in Funktionsargumenten, die Verwendung globaler Variablen und die Verwendung von Handle-Klassen) hat zu viel langsameren Code geführt. –

+0

Ich dachte, 'libpointer' könnte helfen, aber das Konstruieren und Arbeiten mit dem Zeiger scheint teurer zu sein, als ich gedacht hätte. – patrickvacek

+4

Arrays von Strukturen sind langsam im Vergleich zu Strukturen von Arrays. Wenn Ihre Daten dies zulassen, versuchen Sie, in die Struktur der Arrays zu konvertieren, und das wird wahrscheinlich viel schneller. http://www.mathworks.com/help/matlab/matlab_prog/memory-allocation.html#brh72ex-14 – jerad

Antwort

1

Nun, es auf jeden Fall ist das Kopieren los, wenn Sie tun:

temp = database(y + dy, x + dx) 

Dies vielleicht reduziert werden könnte durch die Verwendung:

temp = database(y + dy, x + dx).data 

Aber offensichtlich, dass würde nur funktionieren, wenn Sie nur daran interessiert waren in die Daten in diesem Teil des Codes.

Davon bin ich nicht sicher, ob Sie es umgehen können, ohne unbequeme Methoden zu verwenden, um Ihre Daten zu strukturieren. Zuallererst können Sie Ihren Code benchmarken, nachdem Sie alle temp durch database(y + dy, x + dx) ersetzt haben, um sicherzustellen, dass das Vermeiden der Kopie wirklich hilft. Wenn ja, könnten Sie versuchen, database(y + dy, x + dx) zu einer Unterfunktion zu füttern, da typischerweise Variablen in einer Unterfunktion mit Lesezugriff verwendet werden, wenn dies ausreichend ist. Ich bin mir jedoch nicht sicher, ob dies auch für Teile von Variablen gilt.

Wenn keine der oben genannten hilft, in dem Buch einige der ältesten Ratschläge zu beachten:

Für eine effiziente Berechnungen auf großen Datenmengen, betrachten Matrizen.