Skip to content

Implement Extend::extend_reserve for faster string appending when final size is known #42

@kleinesfilmroellchen

Description

@kleinesfilmroellchen

In spcasm's file handling code, I retrieve text from a file, strip out some characters with an iterator, and then collect the characters into a SmartString. The relevant snippet of code looks like this:

// type correctly inferred to SmartString<LazyCompact> due to other code
let contents = std::fs::read_to_string(&path)?.chars().filter(|c| c != &'\r').collect();

However, since I'm only removing some characters from pre-loaded text, I know an upper bound of text length. If I were able to tell SmartString to preallocate that amount of storage, it would most likely not need to repeatedly reallocate the string during appending from the iterator. Therefore, I would like to rewrite the above code as the following:

let text = std::fs::read_to_string(&path)?;
let text_size = text.len();
let mut contents = String::new();
<SmartString<LazyCompact> as Extend<char>>::extend_reserve(&mut contents, text_size); // <-----
contents.extend(text.chars().filter(|c| c != &'\r'));

This utilizes the unstable extend_one feature which provides extend_reserve. I would be fine with a separate function not in the trait while the feature is unstable since I don't need to access the function through the trait.

All other rewrites of the first snippet, especially the method of iteration, would fundamentally have the same issue and also benefit from this feature.

For a point of reference, the first code snippet is responsible for >16% of runtime on some of my inputs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions