Rust: write!(wr,"foo") wr.write("foo.as_bytes()) рдХреА рддреБрд▓рдирд╛ рдореЗрдВ 10% рд╕реЗ 72% рдзреАрдореА рд╣реИред

рдХреЛ рдирд┐рд░реНрдорд┐рдд 2 рджрд┐рд╕ре░ 2013  ┬╖  9рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: rust-lang/rust

рдпрд╣ рдЙрджрд╛рд╣рд░рдг рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рддреБрдЪреНрдЫ рдорд╛рдорд▓реЗ 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 рдкрд░ рдмреНрд▓реЙрдХ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред
  • рдкрддрд╛ рд▓рдЧрд╛рдПрдБ рдХрд┐ llvm write! рдУрд╡рд░рд╣реЗрдб рдХреЛ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдХреНрдпреЛрдВ рдирд╣реАрдВ рд╣реИред рдХреНрдпрд╛ рдРрд╕реЗ рдХрд╛рд░реНрдп рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд░реЗрдЦрд╛рдВрдХрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдирд╣реАрдВ рд╣реИрдВ? рдореЗрд░реЗ рд╕реНрдХреИрдЯрд░ рд╢реЙрдЯ рдкреНрд░рдпрд╛рд╕ рдХрд╛ рдХреЛрдИ рдкрд░рд┐рдгрд╛рдо рдирд╣реАрдВ рдирд┐рдХрд▓рд╛ред
C-enhancement I-slow T-compiler T-libs

рд╕рднреА 9 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореБрдЭреЗ рд╕рдВрджреЗрд╣ рд╣реИ рдХрд┐ 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)

рджреЛ рд╕рд╛рд▓ рдмрд╛рдж:

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_fmt рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ format_args рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА!, рдЬреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрд╛рдж рд╕реЗ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ! рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ "рд╕реЗрд╡рд╛" рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рд╡реАрдИрд╕реА рдХреА рддреБрд▓рдирд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реЗ рдХреА, рдПрдХ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ "рд╕реЗрдм рд╕реЗ рд╕реЗрдм ... рдИрд╢" рддреБрд▓рдирд╛ред 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! рдкрд░ 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 write! рдХреЛ рдЫреЛрдбрд╝ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрд╣рд╛рдВ рд╕реНрд╡рд░реВрдкрдг рдорд╢реАрдирд░реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╛ рд╕реНрдкрд╖реНрдЯ рддреЗрдЬрд╝ рдкрде рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реНрд╡рд░реВрдкрдг рдорд╢реАрдирд░реА рд╕реНрд╡рдпрдВ рдмрд╣реБрдд рддреЗрдЬрд╝ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

lambda-fairy picture lambda-fairy  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

overvenus picture overvenus  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

wthrowe picture wthrowe  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

dtolnay picture dtolnay  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

pedrohjordao picture pedrohjordao  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ