Skip to content

Showing an AnnotatedString is O(length_string * num_annotations) #72

@KristofferC

Description

@KristofferC

There are many cases where the function at https://github.com/JuliaLang/julia/blob/c6732a79494f604e0f320ea451856a1c10511659/base/strings/annotated.jl#L396-L401 gets called a number of times proportional to the length of the string (leading to quadratic behavior).

push!(annots, map(last, annotations(s, start)))
is one such place.

When you iterate an AnnotatedString character by character (as e.g. escape_string does in Base) it also shows up.

I think it would be good to:

  • do some pre processing of the annotations so that there is no need to do this type of random access lookup of them
  • provide a better iterator over an AnnotatedString that uses something similar to eachregion instead of having to do everything from scratch for every character.

Printing a somewhat long string to stdout is noticeably quite slow.

Aug-02-2024 14-41-23

Some code to generate a long string:

using Random

function generate_annot_string(n)
    colors = [:yellow, :green, :blue, :red]
    offset = 1
    annotations = Tuple{UnitRange{Int64}, Pair{Symbol, Any}}[]
    while true
        col = rand(1:length(colors))
        l = rand(1:10)
        offset + l > n && break
        push!(annotations, (offset:(offset+l), :face => colors[col]))
        offset += l
    end
    s = randstring(n)
    return Base.AnnotatedString(s, annotations)
end

str = generate_annot_string(100000)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions