Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

50% serialization performance regression #629

Closed
dtolnay opened this issue Nov 26, 2016 · 4 comments
Closed

50% serialization performance regression #629

dtolnay opened this issue Nov 26, 2016 · 4 comments
Assignees

Comments

@dtolnay
Copy link
Member

dtolnay commented Nov 26, 2016

Between nightly-2016-11-03 and nightly-2016-11-06 all of my serialization benchmarks here (across all libs, not just Serde) regressed by ~50%. Deserialization not affected.

@dtolnay dtolnay self-assigned this Nov 26, 2016
@dtolnay
Copy link
Member Author

dtolnay commented Nov 26, 2016

This simple case regressed by 70%, from 995μs to 1685μs.

#![feature(test)]

extern crate serde;
extern crate serde_json;
extern crate test;

#[derive(Clone, Default)]
struct Area(u32);

impl serde::Serialize for Area {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer
    {
        let mut state = try!(serializer.serialize_struct("Area", 1));
        try!(serializer.serialize_struct_elt(&mut state, "blockIds", &[(); 0]));
        serializer.serialize_struct_end(state)
    }
}

#[bench]
fn bench(b: &mut test::Bencher) {
    let areas = vec![Area::default(); 65536];
    let len = serde_json::to_string(&areas).unwrap().len();
    let mut buf = Vec::with_capacity(len);
    b.iter(|| {
        buf.clear();
        serde_json::to_writer(&mut buf, &areas).unwrap();
    });
}

@dtolnay
Copy link
Member Author

dtolnay commented Nov 26, 2016

Narrowed down further, this code shows a 40% regression.

#![feature(test)]

extern crate test;

#[bench]
fn bench(b: &mut test::Bencher) {
    const N: usize = 65536;
    let mut buf = Vec::with_capacity(N);
    b.iter(|| {
        buf.clear();
        for _ in 0..N {
            w(&mut buf, b'[').unwrap();
        }
    });
}

#[inline(never)]
fn w(buf: &mut Vec<u8>, b: u8) -> Result<(), ::std::io::Error> {
    buf.extend_from_slice(&[b]);
    Ok(())
}

@dtolnay
Copy link
Member Author

dtolnay commented Nov 26, 2016

Opened rust-lang/rust#38021.

@dtolnay
Copy link
Member Author

dtolnay commented Dec 29, 2016

Verified fixed by rust-lang/rust#38182.

@dtolnay dtolnay closed this as completed Dec 29, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

1 participant