Sto lavorando su un'app iOS che visualizza i dati come un grafico a linee. Il grafico viene disegnato come CGPath
in uno schermo intero personalizzato UIView
e contiene al massimo 320 punti di dati. I dati vengono aggiornati di frequente e il grafico deve essere ridisposto di conseguenza - una frequenza di aggiornamento di 10/sec sarebbe piacevole.Prestazioni quando si disegnano spesso CGPaths
Finora così facile. Sembra, tuttavia, che il mio approccio richieda molto tempo per la CPU. L'aggiornamento del grafico con 320 segmenti a 10 volte al secondo comporta un carico della CPU del 45% per il processo su un iPhone 4S.
Forse sottovaluto il lavoro grafico sotto il cofano, ma per me il carico della CPU sembra molto per quel compito.
Di seguito è la mia funzione drawRect()
che viene chiamata ogni volta che un nuovo set di dati è pronto. N
contiene il numero di punti e points
è un vettore CGPoint*
con le coordinate da disegnare.
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// set attributes
CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor);
CGContextSetLineWidth(context, 1.f);
// create path
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddLines(path, NULL, points, N+1);
// stroke path
CGContextAddPath(context, path);
CGContextStrokePath(context);
// clean up
CGPathRelease(path);
}
Ho provato rendere il percorso di un offline CGContext prima prima di aggiungerlo al layer corrente come suggerito here, ma senza alcun risultato positivo. Ho anche lavorato con un approccio al CALayer direttamente, ma anche questo non ha fatto alcuna differenza.
Qualche suggerimento su come migliorare le prestazioni per questa attività? Oppure il rendering rende semplicemente più lavoro per la CPU che realizzo? OpenGL avrebbe senso/differenza?
Grazie/Andi
Aggiornamento: Ho anche provato ad utilizzare UIBezierPath
invece di CGPath
. Questo post here fornisce una bella spiegazione del perché non è stato di aiuto. Tweaking CGContextSetMiterLimit
et al. anche non ha portato grande sollievo.
Aggiornamento n. 2: Alla fine sono passato a OpenGL. È stata una curva di apprendimento ripida e frustrante, ma l'aumento delle prestazioni è semplicemente incredibile. Tuttavia, gli algoritmi di anti-aliasing di CoreGraphics fanno un lavoro migliore di quello che si può ottenere con il 4x multicampionamento in OpenGL.
Il tuo colore è una costante. Spostalo se drawRect e continua a riutilizzarlo anziché richiederne uno nuovo ogni volta. Idem per il percorso. Poiché StrokePath() "svuota il percorso", è possibile riutilizzare lo stesso percorso oggetto più e più volte. Cosa cambia? – verec
La documentazione afferma che il percorso è stato svuotato, ma almeno nel mio codice non lo è. Continua a crescere. Per quanto riguarda il colore, hai un punto. Era brutto, ma non la soluzione. Grazie. –
Intendi UIBezierPath, giusto? NSBezierPath esiste solo su Mac. –