- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
最近,当我想在延迟后触发一些代码时,我一直在使用 dispatch_after 而不是 performSelector:withObject:afterDelay。代码更简洁,它可以访问封闭范围,我可以将代码放在行内而不是编写一次性方法等。
我的代码可能是这样的:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
delay * NSEC_PER_SEC),
dispatch_get_main_queue(),
^{
//Delayed-execution code goes here.
}
);
但是,我最近发现这段代码的执行时间似乎始终比要求的慢 10%。如果我要求延迟 10 秒,我的 block 将在大约 11 秒后执行。这是在 iOS 设备上。模拟器上的时间似乎非常吻合。
我用来测试的代码非常简单:
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
delay * NSEC_PER_SEC),
dispatch_get_main_queue(),
^{
NSTimeInterval actualDelay = [NSDate timeIntervalSinceReferenceDate] - startTime;
NSLog(@"Requested delay = %.3f. Atual delay = %.3f", delay, actualDelay);
//Delayed-execution code goes here.
}
);
我已经在从 iOS 4S 到 iPad Air 的设备上进行了测试,额外的延迟非常一致。我还没有在 iPhone 4 或 iPad 2 等较旧的设备上进行测试,不过我很快就会这样做。
我可能预计延迟会出现 20-50 毫秒的“倾斜”,但持续 10% - 11% 的超调是奇怪的。
我在我的代码中添加了一个“软糖因素”来调整额外的延迟,但我发现它令人惊讶:
#define delay_fudge 0.912557 //Value calculated based on averages from testing.
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
delay * delay_fudge * NSEC_PER_SEC),
dispatch_get_main_queue(),
^{
NSTimeInterval actualDelay = [NSDate timeIntervalSinceReferenceDate] - startTime;
NSLog(@"Requested delay = %.3f. Actual delay = %.3f", delay, actualDelay);
//Delayed-execution code goes here.
}
);
我可能应该做更多的分析,看看是否有延迟的固定增加加上延迟因子或直接百分比延迟,或者可能是误差的一些非线性比例,但现在一个简单的乘法器似乎做得很好好吧。
最佳答案
您可能听说过 Timer Coalescing and App Nap - 这有助于降低功耗。
您在这里观察到的是将系统事件延迟到某个“回旋余地”的效果,以便能够一起同时执行它们及时,“定时器合并”。这将增加 CPU 停留在节能模式的时间。
对于 dispatch lib,有一个标志可以用来增加“leeway value”的准确性,这最终也会影响计时器的准确性(见下文)。我认为让计时器变得不必要准确不是一个好主意——例如对于移动设备。
我的怀疑是,dispatch_after
将使用具有特定余地值集的调度计时器,这是实现定义的。
您可以使用 dispatch_source_set_timer()
使用调度库实现非常准确的计时器,您还可以在其中指定“余地值”。
另请参阅:dispatch/source.h
/*!
* @typedef dispatch_source_timer_flags_t
* Type of dispatch_source_timer flags
*
* @constant DISPATCH_TIMER_STRICT
* Specifies that the system should make a best effort to strictly observe the
* leeway value specified for the timer via dispatch_source_set_timer(), even
* if that value is smaller than the default leeway value that would be applied
* to the timer otherwise. A minimal amount of leeway will be applied to the
* timer even if this flag is specified.
*
* CAUTION: Use of this flag may override power-saving techniques employed by
* the system and cause higher power consumption, so it must be used with care
* and only when absolutely necessary.
*/
#define DISPATCH_TIMER_STRICT 0x1
...
* Any fire of the timer may be delayed by the system in order to improve power
* consumption and system performance. The upper limit to the allowable delay
* may be configured with the 'leeway' argument, the lower limit is under the
* control of the system.
*
关于ios - 您是否注意到 dispatch_after 在 iOS 设备上运行速度太慢了 ~10%?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21266022/
我最近注意到一个隐藏的进程,它没有出现在进程列表中,但它消耗CPU时间和内存。这是怎么发生的,它是如何编写的,它在做什么,我们如何杀死该进程。 有什么方法可以取消隐藏此类隐藏的进程 最佳答案 简而言之
假设我有一个相当嵌套的 JS 对象,我需要对其进行 JSON 编码: var foo = { "totA": -1, "totB": -1, "totC": "13,052.0
我正在尝试使用 scrapy 抓取一些诗歌,我有这样的文本: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean co
这可能是常识,但我似乎无法找到有关该问题的任何信息。这是一些背景知识: 我有一些页面使用了 Bootstrap 的标签系统。在这些页面的 $(document).ready() 函数中是一些基于 UR
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我创建了一组新的 Controller ,当我尝试归档新代码时,在归档这些 Controller 时发生了这个错误: error: open /Users/owner12/Library/Develo
在 Xcode 12.5.1 中使用 IOS 14.5 部署目标遵循 UIDocumentPickerViewController 的现场 IOS 文档时,出现错误: Incorrect argume
我是一名优秀的程序员,十分优秀!