2010-05-26 9 views
1

dans une application de dessin simple J'ai un modèle qui a un NSMutableArraycurvedPaths contenant toutes les lignes que l'utilisateur a dessinées. Une ligne elle-même est également NSMutableArray, contenant les objets ponctuels. Comme je dessine courbes NSBezier chemins, ma matrice de points a la structure suivante: linePoint, controlPoint, controlPoint, linePoint, controlPoint, controlPoint, etc ... Je pensais avoir un tableau contenant tous les points plus les points de contrôle serait plus efficace que traiter 2 ou 3 tableaux différents.Optimisation d'un dessin dessin de code

Évidemment, ma vue dessine les chemins qu'elle obtient du modèle, ce qui conduit à la vraie question: Y at-il un moyen d'optimiser le code suivant (dans la méthode drawRect de la vue) en termes de vitesse?

int lineCount = [[model curvedPaths] count]; 

// Go through paths 
for (int i=0; i < lineCount; i++) 
{ 
    // Get the Color 
    NSColor *theColor = [model getColorOfPath:[[model curvedPaths] objectAtIndex:i]]; 

    // Get the points 
    NSArray *thePoints = [model getPointsOfPath:[[model curvedPaths] objectAtIndex:i]]; 

    // Create a new path for performance reasons 
    NSBezierPath *path = [[NSBezierPath alloc] init]; 

    // Set the color 
    [theColor set]; 

    // Move to first point without drawing 
    [path moveToPoint:[[thePoints objectAtIndex:0] myNSPoint]]; 

    int pointCount = [thePoints count] - 3; 

    // Go through points 
    for (int j=0; j < pointCount; j+=3) 
    { 
     [path curveToPoint:[[thePoints objectAtIndex:j+3] myNSPoint] 
      controlPoint1:[[thePoints objectAtIndex:j+1] myNSPoint] 
      controlPoint2:[[thePoints objectAtIndex:j+2] myNSPoint]]; 
    } 

    // Draw the path 
    [path stroke]; 

    // Bye stuff 
    [path release]; 
    [theColor release]; 
} 

Merci, xonic

Répondre

4

Hey xon1c, le code semble bon. En général, il est impossible d'optimiser sans mesurer les performances dans des cas spécifiques. Par exemple, disons que le code ci-dessus n'est jamais appelé qu'une seule fois. Il dessine une image dans une vue et n'a jamais besoin d'être redessinée. Supposons que le code ci-dessus prenne 50 millisecondes pour s'exécuter. Vous pouvez le réécrire en openGL et faire toutes les optimisations sous le soleil et obtenir ce temps jusqu'à 20 millisecondes et de façon réaliste les 30 millisecondes que vous avez enregistrées ne fait aucune différence pour tout le monde et vous avez juste perdu votre temps et ajouté une charge de code ... ballonnement qui va être plus difficile à maintenir.

Toutefois, si le code ci-dessus est appelé 50 fois par seconde et la plupart de ces fois il dessine la même chose, alors vous pourriez l'optimiser de façon significative.

Quand il s'agit de dessiner le meilleur moyen d'optimiser est d'éliminer les dessins inutiles.

Chaque fois que vous dessinez, vous recréez les NSBezierPaths - sont-ils toujours différents? Vous pouvez conserver la liste des chemins NSBezier à dessiner, conserver celle-ci en phase avec votre modèle et garder drawrect uniquement pour dessiner les chemins.

Dessinez-vous des zones de votre vue qui n'ont pas besoin d'être redessinées? L'argument de drawrect est la zone de la vue qui a besoin d'être redessinée - vous pouvez tester par rapport à cela (ou getRectsBeingDrawn: count :), mais il se peut dans votre cas que vous sachiez que toute la vue doit être redessinée. Si les trajectoires elles-mêmes ne changent pas souvent, mais que la vue doit souvent être redessinée - par exemple, lorsque les formes des trajectoires ne changent pas mais que leurs positions sont animées et se chevauchent de différentes manières, vous pouvez tracer les trajectoires images (textures) puis à l'intérieur drawrect vous dessiner la texture à la vue au lieu de dessiner le chemin de la vue. Cela peut être plus rapide car la texture n'est créée qu'une seule fois et téléchargée dans la mémoire vidéo qui est plus rapide à dessiner à l'écran. Vous devriez regarder Core Animation si c'est ce que vous devez faire.

Si vous trouvez que le dessin des chemins est trop lent, vous pouvez regarder CGPath

Ainsi, dans l'ensemble, il ne dépend vraiment de ce que vous faites. Le meilleur conseil est, comme toujours, de ne pas tomber dans l'optimisation prématurée. Si votre application n'est pas vraiment trop lente pour vos utilisateurs, votre code est très bien.

+0

Bon point là-bas! Sauver les chemins ne m'est pas venu à l'esprit mais c'est en fait une très bonne idée. La chose est, j'ai une vue transparente sur l'ensemble du bureau afin de permettre à l'utilisateur de dessiner sur différentes fenêtres, ou d'écrire des notes, peu importe. Ainsi, les chemins ne changent pas très souvent, mais se dessinent souvent et un utilisateur peut en effacer un ou plusieurs.Je pense que la texture ne fera pas tout le travail. Mais tout à l'heure j'ai découvert la méthode containsPoint: de NSBezierPath qui va même optimiser mon 'code de chemin d'effacement'! Thx beaucoup mec! – xon1c