Repeat string literals?

Is there any method to create a (const) string with repeat pattern? I know that, "str".repeat(n) could generate a String, but this generate a String object in every call, which is not very efficient.

If we have something like:

"          " == " " * 10;
// or
"          " == repeat!(" ", 10);

we could write some beautiful code:

const PADDING: &str = "##########";
// If we have, const PADDING: &str = "#" * 10;, the program will be nicer.
// further, if the repeat is longer(e.g., "#" * 1000), it is very ugly to write it.
// This is why I want a repeat function generates string literals.
const CONTENT: &str = "abcdefghijklmnopqrst"; // to simulate some generated contents.
use std::time::Instant;
fn main() {
    let mut left_padding = [1, 4, 2, 8, 5, 7].into_iter().cycle();
    let mut right_padding = [1, 4, 2, 8, 5, 7].into_iter().cycle();
    let mut content_length = [8, 5, 7, 1, 4, 2].into_iter().map(|x| x * 2).cycle();
    let now = Instant::now();
    let mut vec=Vec::new();
    for _line in 0..10000 {
        vec.push(format!(
            "{} {} {}",
            PADDING.split_at(left_padding.next().unwrap()).0,
            CONTENT.split_at(content_length.next().unwrap()).0,
            PADDING.split_at(right_padding.next().unwrap()).0,
        ));
    }
    println!("{}", now.elapsed().as_nanos());
    println!("{}",vec.len())
}

it takes 1822150 ns to finish the format progress, if we use "#".repeat(n) (as shown below), 2609921 ns will be taken to finish the program.

const CONTENT: &str = "abcdefghijklmnopqrst";
use std::time::Instant;
fn main() {
    let mut left_padding = [1, 4, 2, 8, 5, 7].into_iter().cycle();
    let mut right_padding = [1, 4, 2, 8, 5, 7].into_iter().cycle();
    let mut content_length = [8, 5, 7, 1, 4, 2].into_iter().map(|x| x * 2).cycle();
    let now = Instant::now();
    let mut vec=Vec::new();
    for _line in 0..10000 {
        vec.push(format!(
            "{} {} {}",
            "#".repeat(left_padding.next().unwrap()),
            CONTENT.split_at(content_length.next().unwrap()).0,
            "#".repeat(right_padding.next().unwrap()),
        ));
    }
    println!("{}", now.elapsed().as_nanos());
    println!("{}",vec.len())
}

Since this is a question about using Rust, it's a better fit for the users forum.

I don't know of a way to create a const string by repetition (though writing a proc macro to do so is not too difficult), but for the specific case of a single character fill you can use the format! syntax to generate a run of said character.

format!("{empty:#>width$}", empty = "", width = 20)

[playground]

1 Like

You can create a &'static str constant by repeating another &'static str constant using const_format::str_repeat.

3 Likes

Oh that's clever, using [_; N] to repeat the string bytes. I'll need to keep that (and the crate) in mind for future decl macro abuse.

Thanks for your answer. It is very hard for me to choose the right forum.

I think this could be "related to the implementation and design of the Rust programming language" (I think I'm talking about add " " == repeat!(" ",10)), rather than " help, discussion, and announcements related to the Rust programming language "

how to choose the right forum?

Users: You want an approach you can use today.

Internals: You want to talk about possibly adding something that you might be able to use a year from now.

2 Likes

Adding something to the Rust language or standard library.

Sorry for the nit.