当我试图生成一个字符串时,我同时使用了format!
,并直接推送到String
中。
直接推入String
需要约40 ns/iter,而使用format!
需要约80 ns/iter(两倍长)。
为什么编译器不把format!
优化成最快的机器码呢?也许我错了,但是format!
的承诺之一就是它应该产生最快的代码。
有没有办法让format!
产生更好的代码?或者在使用它的时候总是会有速度上的损失?
#![feature(test)]
fn do_push(username: &str, password: &str) -> String {
let mut body = String::with_capacity(
"grant_type=password&username=".len()
+ username.len()
+ "&password=".len()
+ password.len(),
);
body.push_str("grant_type=password&username=");
body.push_str(username);
body.push_str("&password=");
body.push_str(password);
return body;
}
fn do_format(username: &str, password: &str) -> String {
format!(
"grant_type=password&username={}&password={}",
username, password
)
}
#[cfg(test)]
mod tests {
extern crate test;
use test::Bencher;
#[bench]
fn bench_push(b: &mut Bencher) {
b.iter(|| do_push("my_real_login", "with my real password"));
}
#[bench]
fn bench_format(b: &mut Bencher) {
b.iter(|| do_format("my_real_login", "with my real password"));
}
}
1条答案
按热度按时间4nkexdtk1#
也许我错了,但是
format!
的承诺之一是它应该产生尽可能快的代码。这从来就不是格式化机器的设计目标。它是为了快速编译而设计的,我想也是为了代码的大小。从来都不是为了速度。
如果你正在寻找一个更快的替代方案(没有手写格式那么快,但是相当快),你可以使用
ufmt
。但是别忘了给字符串分配正确的容量,就像你给
push_str()
所做的一样,这样比较才公平,然后使用write!()
。不过,也有令人振奋的消息:我们有希望。