【问题标题】:CoreGraphics slower on iPhone4 than on 3G/3GSiPhone4 上的 CoreGraphics 比 3G/3GS 上的慢
【发布时间】:2010-08-31 15:16:12
【问题描述】:

我有一个用 CoreGraphics 绘制的图表。

此图表可以水平滚动,并在我们滚动时绘制。

问题是在 3G/3GS 上滚动的速度和性能都不错,但在 iPhone 4 上却比预期的慢。

我想这是与 iPhone 4 的高分辨率有关的问题。对吗?

如何提高 iPhone 4 的性能?框架会自动转换以绘制 iPhone 4 分辨率还是我的工作?

非常感谢。

【问题讨论】:

  • 如果您发布您的绘图代码,我们也许可以帮助您优化它。
  • 您是否比较过运行 iOS 4.0 的 iPhone 4 和 iPhone 3G 的速度?这将告诉您是硬件还是新的操作系统版本导致 2D 图形性能下降。
  • 你应该在 Instruments 中分析你的代码,看看它的哪一部分占用的时间最多,然后看看你是否可以做得更少或不同。
  • 谢谢三位。 @cduhn,我无法发布代码,抱歉,它很大,事实上,代码没有问题,只是在低分辨率设备中绘图速度更快,所以我问是否有人知道这是否是解决的问题。 @hotpaw2 在带有 3.X 的 3G 和带有 4.X 的 3GS 上,性能是完美且相同的。 @Peter 谢谢,我会用 Instruments 追踪它。

标签: iphone core-graphics iphone-4


【解决方案1】:

在 CoreGraphics 处理方面,iPhone 4 可能会慢很多

为您的案例提供一个可能的想法。当用户滚动时,而不是绘制全分辨率,绘制与 CoreGraphics 相关的东西半分辨率上下文。然后将该上下文作为位图并将其放大到全分辨率。这仅适用于 iPhone4,您将失去更好的高分辨率质量,但仅限于用户滚动时。

这是我为在不同设备之间进行测试而编写的一些代码。

全屏显示视图时的结果。

  • 3G,9 FPS
  • 3GS,16 FPS
  • i4,5 FPS(无赖)

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

【讨论】:

    【解决方案2】:

    体验“它更慢”,你能更准确地描述一下吗?我假设滚动的帧速率已经降低到看起来不流畅甚至卡顿的程度。

    如果是这样,并且您确定解决方案是导致此问题的原因,那么我可以看到两种通用方法。

    • 以例如一半的间隔更新,将一半渲染为宽切片。如果 Cocoa Touch 无法实现这一点,您可以从您现在拥有的渲染方法中按时间间隔触发回调。
    • “提前”渲染,以便在滚动到视图中时渲染隐藏在可视区域之外的图形部分。

    我假设您已经查看了视图的“绘图”属性、不透明等,因为它们确实会影响性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 2011-06-30
      • 2011-05-05
      • 2011-04-06
      • 1970-01-01
      相关资源
      最近更新 更多