首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在什么情况下,GCD会对旧设备产生负面的性能影响?

在什么情况下,GCD会对旧设备产生负面的性能影响?
EN

Stack Overflow用户
提问于 2012-04-01 15:56:25
回答 2查看 318关注 0票数 0

我觉得GCD有点奇怪。

首先,我有一个执行大量计算的方法,然后进行一些UI布局计算,并根据结果更新UI。

在没有GCD的情况下,每次调用该方法时,UI都会冻结大约0.5秒

所以我去了GCD做了这个

代码语言:javascript
复制
// INIT
// stored in ivar (called only once!)
dispatch_queue_t q = dispatch_queue_create("com.testcompany.myqueue", NULL);


// WORK
dispatch_async(q, ^(void) {
    [self performHeavyCalculationAndUpdateUI]; // modifies self.calculationData
});

在进行此更改后,该方法将花费大约2-5秒的时间,直到更改出现在UI中。

在串行队列中运行的-performHeavyCalculationAndUpdateUI:中的工作代码以Robert Ryan suggested here的方式调用主队列(主线程)上的一些UI修改代码。

代码语言:javascript
复制
dispatch_async(dispatch_get_main_queue(), ^{
    // Read ivars and objects used during calculation in the serial queue (problem?)
    CalculationData *result = self.calculationData;

    // UI updates like [foo addSubview:bar];
});

在主队列中,我还读取了在串行后台队列中计算过程中使用的一些ivars和对象。这会是个问题吗?

还需要2到5秒才能有什么东西出现。远比没有GCD的时间长。

除了这里我不想在其他地方使用GCD。

有没有其他人经历过这种GCD的问题,并知道解决方案?

我数小时后发现的:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-01 20:20:48

您所描述的问题不是来自GCD,至少不是在您发布的代码中。我制作了一个快速测试函数来记录切换队列所需的时间:

代码语言:javascript
复制
-(IBAction)beginWork:(id)sender{
    NSTimeInterval buttonPushTime = [NSDate timeIntervalSinceReferenceDate];
    // Defined as an ivar : dispatch_queue_t q;
    // created as "q = dispatch_queue_create("com.testcompany.myqueue", NULL);" in viewDidLoad
    dispatch_async(q, ^{
        NSTimeInterval backgroundBeginTime = [NSDate timeIntervalSinceReferenceDate];
        [NSThread sleepForTimeInterval:5.0];
        NSTimeInterval backgroundEndTime = [NSDate timeIntervalSinceReferenceDate];
        dispatch_async(dispatch_get_main_queue(), ^{
            NSTimeInterval backOnMainThreadTime = [NSDate timeIntervalSinceReferenceDate];

            NSLog(@"seconds to start on background thread = %f",backgroundBeginTime-buttonPushTime);
            NSLog(@"seconds to perform in background      = %f",backgroundEndTime-backgroundBeginTime);
            NSLog(@"seconds to get main thread again      = %f",backOnMainThreadTime-backgroundEndTime);
            NSLog(@"total seconds                         = %f",backOnMainThreadTime-buttonPushTime);
        });
    });
}

然后,我在我的iPod触摸第2代(一个可以说是非常老的设备)上运行了这段代码。iOS 4.2.1)。结果如下:

代码语言:javascript
复制
seconds to start on background thread = 0.001747
seconds to perform in background      = 5.000142
seconds to get main thread again      = 0.000190
total seconds                         = 5.002079

在这种情况下,队列切换比时间增加了不到千分之一秒。我建议您添加一些类似的日志,以查找您的延迟。

票数 1
EN

Stack Overflow用户

发布于 2012-04-01 16:35:55

顺便说一句,您每次调用dispatch_queue_create时都执行performHeavyCalculationAndUpdateUI吗?你做了很多次这个沉重的计算吗?如果是这样的话,您可能希望确保只创建一次队列,并根据需要分配给它。(通过将队列创建/发布与调度分离,还可以帮助您诊断导致性能问题的原因.GDC开销或performHeavyCalculationAndUpdateUI中的一些问题。最后,当您完成队列时,是否也执行dispatch_release

有一些GCD开销,但我认为明智地使用创建和释放队列将是谨慎的,也将有助于诊断问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9965852

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档