2016-04-26 7 views
0

Das klingt vielleicht eine dumme Frage; Aber da ich neu im Programmieren bin, dachte ich, einige von Ihnen könnten mir in dieser Hinsicht helfen. Ich habe den folgenden Code-Snippet:Optimieren einer iterativen for-Schleife für iOS App

for k in 0..<64{ 
     for i in 0..<14{ 
      for j in 0..<14{ 
       for di in 0..<5{ 
        for dj in 0..<5{ 
         for q in 0..<32{ 
          A2[0][j][i][k] = A2[0][j][i][k] + T2[0][j+dj+1][i+di+1][q]*W2[k][q][dj][di] 

         } 
        } 
       } 
      } 
     } 
    } 

Hier können Sie sehen, dass die for-Schleife für laufen * 14 * 64 14 * 5 * 5 * 32 = 10.035.200 mal. Als ich mir die Instrumente für die Performance anschaute, fand ich heraus, dass dieser Teil des Codes 57,4% der laufenden Spielzeit ausmachte. Ich habe unten einen Schnappschuss gepostet.

Performance Snapshot!

Gibt es eine Möglichkeit, es zu optimieren? Ich überlegte, es in ein eindimensionales Array umzuwandeln und die Berechnung durchzuführen; aber es macht den Code verwirrender, wenn es um Lesbarkeit geht.

EDIT:

var A2: [[[[Float]]]] = [[[[Float]]]](count: 1, repeatedValue: [[[Float]]](count: 14, repeatedValue: [[Float]](count: 14, repeatedValue: [Float](count: 64, repeatedValue: Float())))) 

var T2: [[[[Float]]]] = [[[[Float]]]](count: 1, repeatedValue: [[[Float]]](count: 20, repeatedValue: [[Float]](count: 20, repeatedValue: [Float](count: 32, repeatedValue: Float())))) 


    for k in 0..<32{ 
     for i in 0..<14{ 
      for j in 0..<14{ 
       T2[0][i+3][j+3][k] = HP1[0][i][j][k] 
      } 
     } 
    } 

HP1 ist ein Array zuvor berechnet; W2 wird vorher berechnet und die obige Berechnung wird entsprechend durchgeführt.

+3

Wie der Code ist nicht schon verwirrend? Erstens, können diese Berechnungen in einem Hintergrundthread durchgeführt werden? Wenn dies der Fall ist, lege das Ding in einen Hintergrundfaden und bleib in Bewegung. Wenn Sie unbedingt dieses verrückte Ding machen müssen und Leistung oberste Priorität hat, dann opfern Sie die Lesbarkeit, um es so optimiert wie möglich zu machen. Weniger Schleifen sind (normalerweise) schneller. – keithbhunter

+0

Wie würden Sie sich annähern, um es zu optimieren? – Nasiba

+0

Können Sie das Problem beschreiben, was genau wird hier berechnet? – DCDC

Antwort

1

Nur ein einfacher Anfang: Sie haben drei Schleifen für i, j und k, und dann haben Sie drei innere Schleifen, wo Sie Dinge zum gleichen Element hinzufügen A2 [0] [i] [j] [k]. Also das Sie nehmen:

for di in 0..<5{ 
    for dj in 0..<5{ 
     for q in 0..<32{ 
      A2[0][j][i][k] = A2[0][j][i][k] + T2[0][j+dj+1][i+di+1][q]*W2[k][q][dj][di] 
     } 
    } 
} 

und ändern Sie es zu:

let sum = A2[0][j][i][k] 
for di in 0..<5{ 
    for dj in 0..<5{ 
     for q in 0..<32{ 
      sum += T2[0][j+dj+1][i+di+1][q]*W2[k][q][dj][di] 
     } 
    } 
} 
A2[0][j][i][k] = sum 

Nun ich nehme an, Sie tun dies mehr als einmal (da 10 Millionen nicht so viel ist), also vielleicht sagen uns, wie Sie Ruf das mehrmals an - vielleicht kannst du dort etwas speichern.

BTW. Mit dieser Art von Problem können Sie einen riesigen Unterschied zwischen einem Debug-Build und einem Release-Build finden.

Wenn Sie das Array W2 neu anordnen können, so dass Sie als W2 [k] [dj] [di] [q] darauf zugreifen können, würde das wahrscheinlich viel helfen.

+0

Danke für die Antwort. Ich werde das jetzt versuchen.Ja, es gibt einen Unterschied zwischen Debug Build und Release Build. Release-Build ist langsamer als Debug. Ist das der Fall? – Nasiba

+0

Release-Build sollte schneller sein. Kompilierst du mit "-OFast"? –

+0

Release-Build ist langsamer? Das ist komisch. – gnasher729

Verwandte Themen