Thoughts about using nightly features from de-facto std crates (e.g. serde)?

While investigating a performance issue of deserialization, I found that serde is repeating some super-inefficient thing.

Namely, it creates serde::__private::de::Content frequently from serde::__private::de::ContentDeserailizer by visiting it and reconstructuring, but ContentDeserailizer has a field named content and the type of it is Content.

So I created a fork (kdy1/serde) and profiled the performance.

Previous

test json_deserialize                     ... bench:     1,226,131 ns/iter (+/- 58,655)

With fork:

test json_deserialize                     ... bench:     339,526 ns/iter (+/- 41,530)

I got this result by invoking cargo bench from kdy1/swc#perf.

I want to make a PR for it, but I'm not sure if it's fine to use nightly-only features from libraries like serde and want to hear opinions about such optimizations before creating one.

#![feature(specialization)] is unsound. You should always use #![feature(min_specialization)] instead.

Of course, I'll change it to use min_specialization if I make a PR

Most libraries, including serde, support stable Rust and will not use unstable features.

It can be optional feature. swc, which is maintained by me, also supports stable rustc.

Well, you can always ask the maintainers of serde.

1 Like

A pattern I've seen in a lot of crates is to have a nightly cargo feature which is disabled by default and explicitly opts into unstable APIs.

That said, I never really use those features because I want my crates to compile on stable and enforce a MSRV with CI, but it might be a nice escape hatch if you need it.

2 Likes