Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
231 views
in Technique[技术] by (71.8m points)

ios - Why does the initial call to NSAttributedString with an HTML string take over 100 times longer than subsequent calls?

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.

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.

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.

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.

Here is the relevant section of code:

-(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];
}

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

The first time we run the method (before parsing the string) only 3 threads exist:

screenshot 1

After the string is parsed, we have 11 threads:

screenshot 2

Now the next time we run the method, most of those web-related threads are still in existence:

screenshot 3

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...