为什么使用HTML字符串对NSAttributedString的初始调用比后续调用花费的时间长100倍? [英] Why does the initial call to NSAttributedString with an HTML string take over 100 times longer than subsequent calls?

查看:268
本文介绍了为什么使用HTML字符串对NSAttributedString的初始调用比后续调用花费的时间长100倍?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在iOS应用程式中显示HTML文字。我决定在 NSAttributedString 内建的 /ios/documentation/uikit/reference/NSAttributedString_UIKit_Additions/Reference/Reference.html#//apple_ref/occ/instm/NSAttributedString/initWithData%3aoptions%3adocumentAttributes%3aerror%3a\">initWithData:options:documentAttributes:错误: 。实际的解析工作非常出色,但是,我似乎遇到了一个非常奇怪的bug,只是似乎表明自己,如果我有调试器附加。

I had a need to display HTML text inside my iOS app. I have decided I will use the built-in method on NSAttributedString, initWithData:options:documentAttributes:error:. The actual parsing works excellently, however, I seem to have come across a very odd bug, that only seems to manifest itself if I have the debugger attached.

第一次这个方法被调用,在运行iOS 7.0.4的iPhone 5S上运行不到1秒,在iPod Touch第5代上运行约1.5秒。

The first time that this method is called, it takes barely under 1 second to run on my iPhone 5S running iOS 7.0.4, and about 1.5 seconds on an iPod Touch 5th generation. The quirk also manifests itself on the simulator, but it is significantly less noticeable, due to the sheer speed of the simulator.

随后的调用只需要大约10-50ms的时间,显然比初始调用快。

Subsequent calls only take around 10-50ms, which is significantly faster than the initial call.

这似乎与缓存的输入字符串没有关系,因为我已经测试了多个输入字符串在我的'真正的应用程序。

This doesn't appear to be related to caching of the input string, as I have tested it with multiple input strings in my 'real' application.

然而,当我运行程序没有调试器,它运行正常,大约10-20ms,这是我希望HTML解析。

However, when I run the program without the debugger, it runs as expected, taking about 10-20ms, which is what I expect HTML parsing to take.

这是代码的相关部分:

-(void) benchmarkMe:(id)sender {
    NSData *data = [testString dataUsingEncoding:NSUTF8StringEncoding];

    NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate];

    // So the complier doesn't keep complaining at me.
    __attribute__((unused))
    NSAttributedString *parsed = [[NSAttributedString alloc] initWithData:data
                                                                  options:@{
                                                                        NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
                                                                        NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)
                                                                    }
                                                       documentAttributes:nil
                                                                    error:nil];

    NSTimeInterval endTime = [[NSDate date] timeIntervalSinceReferenceDate];

    NSString *message = [NSString stringWithFormat:@"Took %lf seconds.", endTime - startTime];

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Benchmark complete!"
                                                        message:message
                                                       delegate:nil
                                              cancelButtonTitle:@"Ok"
                                              otherButtonTitles:nil];
    [alertView show];
}

注意:一个全面工作的项目可在此处获取:

https://github.com/richardjrossiii/NSAttributedStringHTMLBug

Note: A fully working project demonstrating this bug is available here:
https://github.com/richardjrossiii/NSAttributedStringHTMLBug

我疯了吗?有没有什么我在这里失踪?

Am I crazy? Is there something I'm missing here? 1 second is an awfully large amount of time when I'm trying to optimize my app for performance.

我目前的解决方案是在应用程序启动时解析一个虚拟字符串,这是一个非常大量的时间,当我试图优化我的应用程序的性能。 ,但这看起来像一个令人难以置信的解决方法。

My current solution is to parse a 'dummy' string on application launch, but this seems like an incredibly hacky workaround.

推荐答案

这是一个很好的问题。事实证明(至少对我来说),它总是慢第一次调用的方法,无论调试器是否附加。这是为什么:第一次解析一个HTML属性字符串时,iOS会将一个完整的JavaScriptCore引擎和WebKit加载到内存中。观看:

That's a really good question. It turns out that (at least for me) it is always slower the first time I call the method, no matter if the debugger is attached or not. Here is why: The first time you parse an HTML-attributed string, iOS loads a whole JavaScriptCore engine and WebKit into memory. Watch:

第一次运行此方法时(解析字符串之前)只有3个线程:

解析字符串后,我们有11个主题:

现在下次我们运行该方法时,大多数与网络相关的线程仍然存在:

这解释了为什么第一次慢,之后快。

That explains why it's slow the first time and fast thereafter.

这篇关于为什么使用HTML字符串对NSAttributedString的初始调用比后续调用花费的时间长100倍?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆