Fast String Concatenation?

First of all, your tests are just throwing away the result of the formatting. This means the compiler is free to totally ignore your code, because the result is never needed.

Having fixed that, I tried the only thing I could think of: pre-allocate the string to the correct length and don't do any spurious intermediate allocations. I also tried pre-allocating and using formatted write!. First, the code:

#![feature(test)]
extern crate test;
use test::Bencher;

#[bench]
fn format_url_macro(b: &mut Bencher) {
    let index = "test_idx".to_string();
    let name = "test_alias".to_string();

    b.iter(|| {
        format!("/{}/_alias/{}", index, name)
    });
}

#[bench]
fn format_url_concat(b: &mut Bencher) {
    let index = "test_idx".to_string();
    let name = "test_alias".to_string();

    b.iter(|| {
        let mut url = "/".to_string();
        url = url + &index[..] + "/_alias/" + &name[..];
        url
    });
}

#[bench]
fn format_url_push(b: &mut Bencher) {
    let index = "test_idx".to_string();
    let name = "test_alias".to_string();

    b.iter(|| {
        let mut url = String::with_capacity(1 + "/_alias/".len()
            + index.len() + name.len());
        url.push_str("/");
        url.push_str(&index);
        url.push_str("/_alias/");
        url.push_str(&name);
        url
    });
}

#[bench]
fn format_url_write(b: &mut Bencher) {
    let index = "test_idx".to_string();
    let name = "test_alias".to_string();

    b.iter(|| {
        use std::fmt::Write;
        let mut url = String::with_capacity(1 + "/_alias/".len()
            + index.len() + name.len());
        write!(url, "/{}/_alias/{}", index, name).unwrap();
        url
    });
}

Then, the results:

test format_url_concat ... bench:         403 ns/iter (+/- 12)
test format_url_macro  ... bench:         411 ns/iter (+/- 11)
test format_url_push   ... bench:         108 ns/iter (+/- 3)
test format_url_write  ... bench:         156 ns/iter (+/- 4)
4 Likes