CTLineGetOffsetForStringIndex is quadratic(?)

Originator:colin.myr
Number:rdar://31689317 Date Originated:18-Apr-2017 04:21 PM
Status:Closed Resolved:wontfix
Product:macOS + SDK Product Version:10.12.4
Classification:Performance Reproducible:Always
 
From Apple:

There are no plans to address this based on the following:

You can use CTLineEnumerateCaretOffsets() instead.

//
//  main.swift
//  CTChoke
//
//  Created by Colin Rofls on 2017-04-18.
//  Copyright © 2017 Colin Rofls. All rights reserved.
//

import Foundation

func makeString(withLength len: Int) -> String {
    return String(
        bytes:(0..<len).map({ _ in (uint8(arc4random() % 25) + 65) }),
        encoding: String.Encoding.utf8)!
}

func timeClosure(title: String, closure: ()->()) {
    let startTime = CFAbsoluteTimeGetCurrent()
    closure()
    print("\(title) took \(CFAbsoluteTimeGetCurrent() - startTime)")
    
}

for length in [024, 1024*16, 1024*32, 1024*64, 1024*128, 1024*256, 1024*512, 1024*1024] {
    let attrString = NSAttributedString(string: makeString(withLength: length))
    let ctLine = CTLineCreateWithAttributedString(attrString)
    timeClosure(title: "\(length) bytes", closure: {
        let midpoint = length / 2
        let pos = CTLineGetOffsetForStringIndex(ctLine, midpoint, nil)
    })
}

> 24 bytes took 0.000228047370910645
> 16384 bytes took 0.212086021900177
> 32768 bytes took 0.810679018497467
> 65536 bytes took 3.23262000083923
> 131072 bytes took 13.2235760092735
> 62144 bytes took 59.6346539855003

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!