rustc_serialize: specialize opaque encoding of some u8 sequences

This commit is contained in:
Tyson Nottingham 2020-12-16 19:03:31 -08:00
parent 417fe47065
commit a4daa63a90
6 changed files with 32 additions and 21 deletions

View file

@ -11,12 +11,8 @@ use smallvec::{Array, SmallVec};
impl<S: Encoder, A: Array<Item: Encodable<S>>> Encodable<S> for SmallVec<A> {
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_seq(self.len(), |s| {
for (i, e) in self.iter().enumerate() {
s.emit_seq_elt(i, |s| e.encode(s))?;
}
Ok(())
})
let slice: &[A::Item] = self;
slice.encode(s)
}
}
@ -292,12 +288,8 @@ where
impl<E: Encoder, T: Encodable<E>> Encodable<E> for Rc<[T]> {
fn encode(&self, s: &mut E) -> Result<(), E::Error> {
s.emit_seq(self.len(), |s| {
for (index, e) in self.iter().enumerate() {
s.emit_seq_elt(index, |s| e.encode(s))?;
}
Ok(())
})
let slice: &[T] = self;
slice.encode(s)
}
}
@ -315,12 +307,8 @@ impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<[T]> {
impl<E: Encoder, T: Encodable<E>> Encodable<E> for Arc<[T]> {
fn encode(&self, s: &mut E) -> Result<(), E::Error> {
s.emit_seq(self.len(), |s| {
for (index, e) in self.iter().enumerate() {
s.emit_seq_elt(index, |s| e.encode(s))?;
}
Ok(())
})
let slice: &[T] = self;
slice.encode(s)
}
}

View file

@ -14,6 +14,7 @@ Core encoding and decoding interfaces.
#![feature(nll)]
#![feature(associated_type_bounds)]
#![cfg_attr(bootstrap, feature(min_const_generics))]
#![feature(min_specialization)]
#![cfg_attr(test, feature(test))]
#![allow(rustc::internal)]

View file

@ -316,3 +316,15 @@ impl<'a> serialize::Decoder for Decoder<'a> {
err.to_string()
}
}
// Specialize encoding byte slices. The default implementation for slices encodes and emits each
// element individually. This isn't necessary for `u8` slices encoded with an `opaque::Encoder`,
// because each `u8` is emitted as-is. Therefore, we can use a more efficient implementation. This
// specialization applies to encoding `Vec<u8>`s, etc., since they call `encode` on their slices.
impl serialize::Encodable<Encoder> for [u8] {
fn encode(&self, e: &mut Encoder) -> EncodeResult {
serialize::Encoder::emit_usize(e, self.len())?;
e.emit_raw_bytes(self);
Ok(())
}
}

View file

@ -527,7 +527,7 @@ impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<T> {
}
impl<S: Encoder, T: Encodable<S>> Encodable<S> for [T] {
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
default fn encode(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_seq(self.len(), |s| {
for (i, e) in self.iter().enumerate() {
s.emit_seq_elt(i, |s| e.encode(s))?