2013-03-18 9 views
8

Eine Bildverarbeitungsanwendung läuft schnell auf dem Simulator, ist aber wirklich langsam auf einem echten Gerät (iPhone 4GS).iOS und Objective-C: die meiste CPU-Zeit wird in [NSObject release] und [NSObject retain] ausgegeben, aber die Klassenmethode führt keine Speicheroperationen aus

Wenn die Anwendung unter „Instrumente“ läuft, sehe ich die folgende Aufrufbaum:

enter image description here

Beachten Sie, dass die Anrufe innerhalb des roten Kreises sind fast alle von der CPU-Zeit des Verfahrens nehmen gemeldet .

Das betreffende Verfahren ist eine Klassenmethode (keine Instanz-Methode), mit dem folgenden Code:

@implementation Line2F 

+ (CGFloat)signTested:(Point2F *)tested p1:(Point2F *)p1 p2:(Point2F *)p2 
{ 
    return [Line2F signTestedX:tested.x testedY:tested.y 
          p1x:p1.x p1y:p1.y 
          p2x:p2.x p2y:p2.y]; 
} 

+ (CGFloat)signTestedX:(CGFloat)testedX testedY:(CGFloat)testedY 
        p1x:(CGFloat)p1x p1y:(CGFloat)p1y 
        p2x:(CGFloat)p2x p2y:(CGFloat)p2y 
{ 
    return (testedX - p2x) * (p1y - p2y) - (p1x - p2x) * (testedY - p2y); 
} 

@end 

Kann mir jemand erklären, warum die meisten der CPU-Zeit auf [NSObject release] und [NSObject retain] ausgegeben wird?

Antwort

3

Wenn es nichts besseres weiß, behält ARC alle Argumente für eine Methode und gibt sie beim Beenden der Methode frei (siehe this objc-language mailing list email).

Sie können dies vermeiden, indem Sie die Argumente für +signTested:p1:p2: entweder mit __weak oder __unsafe_unretained annotieren, je nach Ihren Bedürfnissen.

+3

Das Problem ist nicht in '+ signTestedX: getestetY: p1x: p1y: p2x: p2y:' was die CGFloat Argumente übernimmt; Wie Sie bemerken, sind Floats keine Objekte und die Semantik würde keinen Sinn ergeben. Das Problem liegt in '+ signTested: p1: p2:', das durch '+ signTestedX: testedY: p1x: p1y: p2x: p2y:' aufruft und 'Point2F' Argumente übernimmt, die (wie es scheint) Objekte sind, die _can_ beibehalten werden können/freigegeben. – frozendevil

+1

Das Übergeben einer __weak-Anweisung hat immer noch einige ARC-Verarbeitung, ist aber schneller. Die einzige Möglichkeit, die ich komplett entfernen konnte, besteht darin, CGFloat anstelle von Objekten zu übergeben. – Guy

1

Nun könnte eine Menge Zeug sein. Wie FrozenDevil sagt, könnte es mit ARC verwandt werden, wenn Sie es verwenden. Ich stelle mir vor, dass die Methode höchstwahrscheinlich unterschiedliche Zeiten innerhalb einer großen Schleife genannt wird. Versuchen Sie, schwache Referenzen zu übergeben, aber natürlich müssen Sie sicher sein, dass sie für den gesamten Prozess existieren. Ich würde auch versuchen, die Schleifeneinbettung jedes Zyklus in einem Autorelease-Pool zu optimieren.