μ΄ μμ μ μ¬μν κ²½μ° μμμ 보μ¬μ€λλ€ write!(wr, "foo")
ν¨μ¬ λλ¦° μ νλ³΄λ€ wr.write("foo".as_bytes())
:
extern mod extra;
use std::io::mem::MemWriter;
use extra::test::BenchHarness;
#[bench]
fn bench_write_value(bh: &mut BenchHarness) {
bh.iter(|| {
let mut mem = MemWriter::new();
for _ in range(0, 1000) {
mem.write("abc".as_bytes());
}
});
}
#[bench]
fn bench_write_ref(bh: &mut BenchHarness) {
bh.iter(|| {
let mut mem = MemWriter::new();
let wr = &mut mem as &mut Writer;
for _ in range(0, 1000) {
wr.write("abc".as_bytes());
}
});
}
#[bench]
fn bench_write_macro1(bh: &mut BenchHarness) {
bh.iter(|| {
let mut mem = MemWriter::new();
let wr = &mut mem as &mut Writer;
for _ in range(0, 1000) {
write!(wr, "abc");
}
});
}
#[bench]
fn bench_write_macro2(bh: &mut BenchHarness) {
bh.iter(|| {
let mut mem = MemWriter::new();
let wr = &mut mem as &mut Writer;
for _ in range(0, 1000) {
write!(wr, "{}", "abc");
}
});
}
μ΅μ ν μμ:
running 4 tests
test bench_write_macro1 ... bench: 280153 ns/iter (+/- 73615)
test bench_write_macro2 ... bench: 322462 ns/iter (+/- 24886)
test bench_write_ref ... bench: 79974 ns/iter (+/- 3850)
test bench_write_value ... bench: 78709 ns/iter (+/- 4003)
test result: ok. 0 passed; 0 failed; 0 ignored; 4 measured
--opt-level=3
:
running 4 tests
test bench_write_macro1 ... bench: 62397 ns/iter (+/- 5485)
test bench_write_macro2 ... bench: 80203 ns/iter (+/- 3355)
test bench_write_ref ... bench: 55275 ns/iter (+/- 5156)
test bench_write_value ... bench: 56273 ns/iter (+/- 7591)
test result: ok. 0 passed; 0 failed; 0 ignored; 4 measured
μ΄λ₯Ό κ°μ νκΈ° μν΄ μ°λ¦¬κ° ν μ μλ μΌμ΄ μμ΅λκΉ? λͺ κ°μ§ μ΅μ μ μκ°ν μ μμ§λ§ λ λ§μ μ΅μ μ΄ μμ΅λλ€.
write!
wr.write("foo".as_bytes())
λ‘ μ»΄νμΌν©λλ€. μ΄ κ²½λ‘λ‘ κ°λ©΄ str write!("foo {} {}", "bar", "baz")
μ리μ¦λ λ³ννλ κ²μ΄ μ’μ΅λλ€.wr.write_str("foo")
. λ΄κ° μ΄ν΄ν λ°λ‘λ #6164μμ μ°¨λ¨λ©λλ€.write!
μ€λ²ν€λλ₯Ό μ΅μ νν μ μλ μ΄μ λ₯Ό νμ
νμμμ€. μΈλΌμΈλμ§ μμμΌ νλ ν¨μκ° μμ΅λκΉ? λ΄ μ€μΊν° μ· μλλ μ΄λ€ κ²°κ³Όλ μ»μ§ λͺ»νμ΅λλ€.fn bench_write_ref
κ° κ°μ ν΅νλ₯Ό νμ§ μλ κ² κ°μ΅λλ€. μ΄κ²μ μΆκ°
#[inline(never)]
fn writer_write(w: &mut Writer, b: &[u8]) {
w.write(b);
}
#[bench]
fn bench_write_virt(bh: &mut BenchHarness) {
bh.iter(|| {
let mut mem = MemWriter::new();
let wr = &mut mem as &mut Writer;
for _ in range(0, 1000) {
writer_write(wr, "abc".as_bytes());
}
});
}
--opt-level 3
running 5 tests
test bench_write_macro1 ... bench: 680823 ns/iter (+/- 34497)
test bench_write_macro2 ... bench: 950790 ns/iter (+/- 72309)
test bench_write_ref ... bench: 505846 ns/iter (+/- 41965)
test bench_write_value ... bench: 511815 ns/iter (+/- 36681)
test bench_write_virt ... bench: 553466 ns/iter (+/- 43716)
λ°λΌμ κ°μ ν΅νκ° μν₯μ λ―ΈμΉμ§λ§ μ΄ λ²€μΉμμ νμλλ write!()
μ λλ¦Όμ μμ ν μ€λͺ
νμ§λ λͺ»ν©λλ€.
λ²κ·Έ λΆλ₯λ₯Ό μν΄ λ°©λ¬Έν©λλ€. μ΄κ²μ μ¬μ ν ββμ‘΄μ¬νλ κ² κ°μ΅λλ€. λ²€μΉλ§ν¬λ₯Ό μ€ννλ μ½λλ λ€μκ³Ό κ°μ΅λλ€.
extern crate test;
use std::io::MemWriter;
use test::Bencher;
#[bench]
fn bench_write_value(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = MemWriter::new();
for _ in range(0u, 1000) {
mem.write("abc".as_bytes());
}
});
}
#[bench]
fn bench_write_ref(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = MemWriter::new();
let wr = &mut mem as &mut Writer;
for _ in range(0u, 1000) {
wr.write("abc".as_bytes());
}
});
}
#[bench]
fn bench_write_macro1(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = MemWriter::new();
let wr = &mut mem as &mut Writer;
for _ in range(0u, 1000) {
write!(wr, "abc");
}
});
}
#[bench]
fn bench_write_macro2(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = MemWriter::new();
let wr = &mut mem as &mut Writer;
for _ in range(0u, 1000) {
write!(wr, "{}", "abc");
}
});
}
μ΅μ ν μμ΄:
running 4 tests
test bench_write_macro1 ... bench: 1470468 ns/iter (+/- 291966)
test bench_write_macro2 ... bench: 1799612 ns/iter (+/- 316293)
test bench_write_ref ... bench: 1336574 ns/iter (+/- 251664)
test bench_write_value ... bench: 1317880 ns/iter (+/- 254668)
test result: ok. 0 passed; 0 failed; 0 ignored; 4 measured
--opt-level=3
:
running 4 tests
test bench_write_macro1 ... bench: 127671 ns/iter (+/- 1452)
test bench_write_macro2 ... bench: 196158 ns/iter (+/- 2053)
test bench_write_ref ... bench: 43881 ns/iter (+/- 453)
test bench_write_value ... bench: 43859 ns/iter (+/- 336)
test result: ok. 0 passed; 0 failed; 0 ignored; 4 measured
λ€μ μ½λλ₯Ό μ¬μ©νλ©΄ μ¬μ ν λ¬Έμ κ° μμ΅λλ€.
#![allow(unused_must_use)]
#![feature(test)]
extern crate test;
use std::io::Write;
use std::vec::Vec;
use test::Bencher;
#[bench]
fn bench_write_value(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = Vec::new();
for _ in 0..1000 {
mem.write("abc".as_bytes());
}
});
}
#[bench]
fn bench_write_ref(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = Vec::new();
let wr = &mut mem as &mut Write;
for _ in 0..1000 {
wr.write("abc".as_bytes());
}
});
}
#[bench]
fn bench_write_macro1(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = Vec::new();
let wr = &mut mem as &mut Write;
for _ in 0..1000 {
write!(wr, "abc");
}
});
}
#[bench]
fn bench_write_macro2(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = Vec::new();
let wr = &mut mem as &mut Write;
for _ in 0..1000 {
write!(wr, "{}", "abc");
}
});
}
μΌλ°μ μΌλ‘ λ€μκ³Ό κ°μ κ²μ μ 곡ν©λλ€.
$ cargo bench
running 4 tests
test bench_write_macro1 ... bench: 21,604 ns/iter (+/- 82)
test bench_write_macro2 ... bench: 29,273 ns/iter (+/- 85)
test bench_write_ref ... bench: 1,396 ns/iter (+/- 387)
test bench_write_value ... bench: 1,391 ns/iter (+/- 163)
λλ λ°€λ§λ€ λ Ήκ³Ό κ±°μ κ°μ κ²°κ³Όλ₯Ό μ»μμ΅λλ€.
κΈ°λ‘μ μν΄ v1.20.0-nightly
:
$ cargo bench
running 4 tests
test bench_write_macro1 ... bench: 36,556 ns/iter (+/- 69)
test bench_write_macro2 ... bench: 54,377 ns/iter (+/- 958)
test bench_write_ref ... bench: 13,730 ns/iter (+/- 24)
test bench_write_value ... bench: 13,755 ns/iter (+/- 81)
μ€λ:
running 4 tests
test bench_write_macro1 ... bench: 16,220 ns/iter (+/- 982)
test bench_write_macro2 ... bench: 25,542 ns/iter (+/- 2,220)
test bench_write_ref ... bench: 4,889 ns/iter (+/- 314)
test bench_write_value ... bench: 4,819 ns/iter (+/- 956)
2 λ ν:
running 4 tests
test bench_write_macro1 ... bench: 17,561 ns/iter (+/- 174)
test bench_write_macro2 ... bench: 23,285 ns/iter (+/- 2,771)
test bench_write_ref ... bench: 3,234 ns/iter (+/- 194)
test bench_write_value ... bench: 3,238 ns/iter (+/- 123)
test result: ok. 0 passed; 0 failed; 0 ignored; 4 measured; 0 filtered out
β― rustc +nightly --version
rustc 1.47.0-nightly (30f0a0768 2020-08-18)
μ°¨μ΄μ μ΄ io::Writeμ fmt::Writeμ ꡬνμ μλμ§, μλλ©΄ write μ΄ν κ΄λ ¨μ±μ΄ μλ format_args!λ₯Ό μꡬνλ write_fmtμ μΈλΆμ¬νμ μλμ§ κΆκΈνμ΅λλ€. λ κ²½μ° λͺ¨λ "μ 곡"νλλ‘ μμ²ν μ μμ΅λλ€.
μ΄μ λν λ λ§μ μ 보λ₯Ό μ°ΎκΈ° μν΄ Vecμ Stringκ³Ό λΉκ΅νλλ°, μ΄λ κ²λ³΄κΈ°μ "apple to apple...ish" λΉκ΅μ λλ€. https://gist.github.com/workingjubilee/2d2e3a7fded1c2101aafb51dc79a7ec5
running 10 tests
test string_write_fmt ... bench: 10,053 ns/iter (+/- 1,141)
test string_write_macro1 ... bench: 10,177 ns/iter (+/- 2,363)
test string_write_macro2 ... bench: 17,499 ns/iter (+/- 1,847)
test string_write_ref ... bench: 2,270 ns/iter (+/- 265)
test string_write_value ... bench: 2,333 ns/iter (+/- 126)
test vec_write_fmt ... bench: 15,722 ns/iter (+/- 1,673)
test vec_write_macro1 ... bench: 15,767 ns/iter (+/- 1,638)
test vec_write_macro2 ... bench: 23,968 ns/iter (+/- 8,942)
test vec_write_ref ... bench: 2,296 ns/iter (+/- 178)
test vec_write_value ... bench: 2,230 ns/iter (+/- 235)
test result: ok. 0 passed; 0 failed; 0 ignored; 10 measured; 0 filtered out
μ΄ μμ μμ write!
μμ Stringμ΄ μ€μ λ‘ Vecλ³΄λ€ μ€λ²ν€λκ° μ λ€λ μ¬μ€μ΄ ν₯λ―Έλ‘λ€λ κ²μ μμμ΅λλ€(λ²€μΉλ§ν¬λ λΆμ°μ΄ λμ§λ§ μΆ©λΆν μμ¬νλ κ²μΌλ‘ κ°μ£Όνμ΅λλ€).
κ·Έ λ€μ λλ λ³΄κ³ λ³΄μλ€:
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> {
// Create a shim which translates an io::Write to a fmt::Write and saves
// off I/O errors. instead of discarding them
struct Adaptor<'a, T: ?Sized + 'a> {
inner: &'a mut T,
error: Result<()>,
}
/* More code related to implementing and using the resulting shim,
* seemingly involving a lot of poking a reference at runtime??? */
}
κ·Έλμ λλ λ μ΄μ λλΌμ§ μμ΅λλ€.
μ΄λ€ κ²½μ°μλ λΉ λ₯Έ κ²½λ‘ μ§μ μ΄ κ°λ₯νλ€κ³ μκ°νμ§λ§, μ¬κΈ°μλ μ€μ λ‘ μ¬κ³Ό λ μ¬κ³Ό λΉκ΅κ° μλλλ€. μ£Όν©μμ write_fmt
μ΄λ©° λ€μν νμν κΈ°κ³λ₯Ό μ¬μ©ν΄μΌ ν©λλ€. νμν κ²μ write!
ν¬λ§· κΈ°κ³κ° νμνμ§ μμ κ°λ¨ν κ²½μ°μ write_fmt
λ₯Ό 건λλ°μ΄μΌ νκ±°λ λͺ
λ°±ν λΉ λ₯Έ κ²½λ‘μ κ²½μ° ν¬λ§· κΈ°κ³ μμ²΄κ° ν¨μ¬ λ λΉ¨λΌμΌ νλ€λ κ²μ
λλ€.