CoreGraphics медленнее на iPhone4, чем на 3G / 3GS

У меня есть график, нарисованный с помощью CoreGraphics.

Эту диаграмму можно прокручивать по горизонтали, и она рисуется, когда мы ее прокручиваем.

Проблема в том, что в 3G / 3GS скорость и производительность прокрутки хорошие, но на iPhone 4 медленнее, чем ожидалось.

Я полагаю, что это проблема, связанная с более высоким разрешением iPhone 4. Это правильно?

Как я могу увеличить производительность на iPhone 4? Есть ли в фреймворке автоматическое преобразование для рисования на разрешении iPhone 4 или это моя работа?

Большое спасибо.

 cduhn31 авг. 2010 г., 17:33
Если вы опубликуете свой код для рисования, мы сможем помочь вам оптимизировать его.
 Peter Hosey31 авг. 2010 г., 22:17
Вы должны профилировать свой код в Instruments и посмотреть, какая его часть занимает больше всего времени, а затем посмотреть, сможете ли вы сделать это меньше или иначе.
 emenegro01 сент. 2010 г., 09:39
Спасибо всем троим. @ Cduhn, я не могу опубликовать код, извините, он огромен, и, на самом деле, с кодом проблем нет, просто в устройствах с низким разрешением рисование происходит быстрее, поэтому я спросил, знает ли кто-нибудь, проблема разрешения. @ hotpaw2 Производительность безупречна и одинакова на 3G с 3.X и на 3GS с 4.X. @Peter Спасибо, я буду отслеживать это с помощью инструментов.
 hotpaw231 авг. 2010 г., 18:18
Вы сравнивали скорость iPhone 4 с iPhone 3G на iOS 4.0? Это скажет вам, является ли аппаратное обеспечение или новая версия ОС причиной замедления производительности 2D-графики.

Ответы на вопрос(2)

Опыт «это медленнее», не могли бы вы описать это более точно? Я предполагаю, что частота кадров прокрутки была снижена до уровня, где она не выглядит гладкой или даже заикается.

Если это так, и если вы уверены, что причиной этого является разрешение, я вижу два основных метода.

обновить, например, с половиной интервала, отображая половину как широкие срезы. Если Cocoa Touch не облегчает это, вы можете вызвать обратный вызов через определенный интервал времени с помощью метода рендеринга, который вы используете сейчас.визуализировать «дальше заранее», чтобы часть графика, скрытая дальше за пределами видимой области, визуализировалась, когда она прокручивалась в поле зрения.

Я предполагаю, что вы уже смотрели на свойства "Рисование" вида, непрозрачности и т. Д., Поскольку они влияют на производительность.

Решение Вопроса

много медленнее, когда дело доходит до обработки CoreGraphics.

Одна возможная идея для вашего случая. Когда пользователь прокручивает, а не рисует полное разрешение, нарисуйте ваши связанные с CoreGraphics вещи в контексте с половинным разрешением. Затем возьмите этот контекст в качестве растрового изображения и масштабируйте его до полного разрешения. Это будет только для iPhone4, и вы потеряете хорошее высокое разрешение, но только тогда, когда пользователь выполняет прокрутку.

Вот код, который я написал для тестирования между различными устройствами.

Мои результаты при отображении в полноэкранном режиме.

3G,9 кадров в секунду3GS,16 FPSi4,5 кадров в секунду (Облом)

CoreGraphicsTestView.h

#import <UIKit/UIKit.h>
@interface CoreGraphicsTestView : UIView 
{
    int displayCounter;
    float displayInterval;
    char fps[50];
}
@end

CoreGraphicsTestView.m

#import "CoreGraphicsTestView.h"
#define RNDN(s, e) ((((CGFloat)rand() / (CGFloat)INT_MAX) * ((e)-(s)) + (s)))
#define RNDX(s, e, r) (RNDN((s), (e)) * (r).size.width)
#define RNDY(s, e, r) (RNDN((s), (e)) * (r).size.height)
#define RNDR(r) (CGRectMake(RNDX(0,0.50,(r)),RNDY(0,0.50,(r)),RNDX(0.50,1.0,(r)),RNDY(0.50,1.0,(r))))
@implementation CoreGraphicsTestView
- (id)initWithFrame:(CGRect)frame 
{
    if ((self = [super initWithFrame:frame])) 
    {
        self.backgroundColor = [UIColor blackColor];
        srand(time(NULL));
        fps[0] = '\0';
    }
    return self;
}
- (void)updateDisplayCounter:(CGContextRef)c rect:(CGRect)rect
{
    displayCounter++;
    float now = (float)clock() / (float)CLOCKS_PER_SEC;
    if (now - displayInterval > 1)
    {
        sprintf(fps, "%0.0f", displayCounter / (now - displayInterval));
        printf("%s\n", fps);
        displayInterval = now;
        displayCounter = 0;
    }
    CGContextTranslateCTM(c, 5, 40);
    CGContextScaleCTM(c, 1.0, -1.0); 
    CGContextSetFillColorWithColor(c, [UIColor whiteColor].CGColor);
    CGContextSelectFont(c, "Arial", 18, kCGEncodingMacRoman);
    CGContextShowTextAtPoint(c, 0, 0, fps, strlen(fps));
}
- (void)setRandomColor:(CGContextRef)c
{
    CGFloat components[4] = {1,RNDN(0, 1),RNDN(0, 1),RNDN(0, 1)};
    CGContextSetFillColor(c, components);
}
- (void)drawRect:(CGRect)rect
{
    CGContextRef c = UIGraphicsGetCurrentContext(); 
    for (int i=0;i<5;i++)
    {
        [self setRandomColor:c];
        CGContextFillRect(c, RNDR(rect));
        [self setRandomColor:c];
        CGContextFillEllipseInRect(c, RNDR(rect));
    }
    [self updateDisplayCounter:c rect:rect];
    [self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:0.0];
}
@end

Ваш ответ на вопрос