Memory optimization of NSAttributedString
Memory optimization of NSAttributedString
- Subject: Memory optimization of NSAttributedString
- From: Charles Jenkins <email@hidden>
- Date: Sun, 22 Mar 2015 08:39:40 -0400
My app uses lots of attributed strings in “subdocuments” which get moved into and out of a text edit window.
I began to wonder if I needed to add a cache for paragraph styles and string attributes, because when each subdocument gets loaded, I’m repetitively deserializing identical attributes to apply to the strings.
Today I wrote the first draft of a test to see what happens when you blindly and repetitively instantiate the same attributes:
func attributedStringsWithNoCache() {
var array = [NSAttributedString]()
let fm = NSFontManager.sharedFontManager()
for index in 1...30 {
var font = NSFont( name:"Times", size:12.0 );
font = fm.convertFont( font!, toHaveTrait:NSFontTraitMask.BoldFontMask )
if ( index % 3 == 0 ) {
font = fm.convertFont( font!, toHaveTrait:NSFontTraitMask.ItalicFontMask )
}
var para = NSMutableParagraphStyle();
para.lineSpacing = 1.4
para.alignment = NSTextAlignment.CenterTextAlignment;
let attributes = [
"StyleName":"Bold",
NSFontAttributeName:font!,
NSParagraphStyleAttributeName:para
];
var attrStr = NSAttributedString( string:"Bold Para \(index)", attributes:attributes );
array.append( attrStr );
}
for index in 1...30 {
var font = NSFont( name:"Times", size:10.0 );
var para = NSMutableParagraphStyle();
para.lineSpacing = 1.2
para.alignment = NSTextAlignment.LeftTextAlignment;
let attributes = [
"StyleName":"Roman",
NSFontAttributeName:font!,
NSParagraphStyleAttributeName:para
];
var attrStr = NSAttributedString( string:"Roman Para \(index)", attributes:attributes );
array.append( attrStr );
}
var fontDict = [NSFont:Int]()
var attrDict = [NSDictionary:Int]()
var paraDict = [NSParagraphStyle:Int]()
for attrStr in array {
attrStr.enumerateAttributesInRange(
NSRange( location:0, length:attrStr.length ),
options:NSAttributedStringEnumerationOptions.allZeros,
usingBlock:{ ( attributes, Range, stop ) -> Void in
attrDict[ attributes ] = 1
if let para = attributes[ NSParagraphStyleAttributeName ] as? NSParagraphStyle {
paraDict[ para ] = 1
}
if let font = attributes[ NSFontAttributeName ] as? NSFont {
fontDict[ font ] = 1
}
})
}
println( "NO CACHE:\nFound \(fontDict.count) fonts and \(paraDict.count) paragraph styles in \(attrDict.count) attribute dictionaries" )
}
I expected the result to say it found 3 fonts and 60 paragraph styles in 60 attribute dictionaries. (I know the system uniquifies fonts.) But when I run the test, I get the best result possible—3 fonts and 2 paragraph styles in 3 attribute dictionaries—as if NSAttributedString already uniquifies everything.
Is my test bad somehow, or am I really seeing that the text system already optimizes memory usage by uniquifying all attribute dictionaries, so I can forget about doing any caching of my own?
—
Charles
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden