Skip to content

Commit 360b946

Browse files
committed
Construct skipped fields only after reading all non-skipped fields
This should increase performance if construction of default object is expensive
1 parent e383366 commit 360b946

File tree

1 file changed

+34
-19
lines changed

1 file changed

+34
-19
lines changed

serde_derive/src/de.rs

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -771,19 +771,26 @@ fn read_fields_in_order(
771771
let expecting = cattrs.expecting().unwrap_or(&expecting);
772772

773773
let mut index_in_seq = 0_usize;
774-
let let_values = vars.clone().zip(fields).map(|(var, field)| {
775-
if field.attrs.skip_deserializing() {
776-
let default = Expr(expr_is_missing(field, cattrs));
777-
quote! {
778-
let #var = #default;
779-
}
780-
} else {
774+
let let_values = vars.clone().zip(fields).filter_map(|(var, field)| {
775+
if !field.attrs.skip_deserializing() {
781776
let read = read_field(params, index_in_seq, field, expecting);
782777
index_in_seq += 1;
783-
quote! {
778+
779+
return Some(quote! {
784780
let #var = #read;
785-
}
781+
});
782+
}
783+
None
784+
});
785+
let let_skipped = vars.clone().zip(fields).filter_map(|(var, field)| {
786+
if field.attrs.skip_deserializing() {
787+
let default = Expr(expr_is_missing(field, cattrs));
788+
789+
return Some(quote! {
790+
let #var = #default;
791+
});
786792
}
793+
None
787794
});
788795

789796
let mut result = if is_struct {
@@ -822,6 +829,7 @@ fn read_fields_in_order(
822829
quote_block! {
823830
#let_default
824831
#(#let_values)*
832+
#(#let_skipped)*
825833
_serde::__private::Ok(#result)
826834
}
827835
}
@@ -890,15 +898,9 @@ fn read_fields_in_order_in_place(
890898
let expecting = cattrs.expecting().unwrap_or(&expecting);
891899

892900
let mut index_in_seq = 0usize;
893-
let write_values = fields.iter().map(|field| {
894-
let member = &field.member;
895-
896-
if field.attrs.skip_deserializing() {
897-
let default = Expr(expr_is_missing(field, cattrs));
898-
quote! {
899-
self.place.#member = #default;
900-
}
901-
} else {
901+
let write_values = fields.iter().filter_map(|field| {
902+
if !field.attrs.skip_deserializing() {
903+
let member = &field.member;
902904
let value_if_none = match field.attrs.default() {
903905
attr::Default::Default => quote!(
904906
self.place.#member = _serde::__private::Default::default();
@@ -936,8 +938,20 @@ fn read_fields_in_order_in_place(
936938
}
937939
};
938940
index_in_seq += 1;
939-
write
941+
return Some(write);
940942
}
943+
None
944+
});
945+
let write_skipped = fields.iter().filter_map(|field| {
946+
if field.attrs.skip_deserializing() {
947+
let member = &field.member;
948+
let default = Expr(expr_is_missing(field, cattrs));
949+
950+
return Some(quote! {
951+
self.place.#member = #default;
952+
});
953+
}
954+
None
941955
});
942956

943957
let this_type = &params.this_type;
@@ -959,6 +973,7 @@ fn read_fields_in_order_in_place(
959973
quote_block! {
960974
#let_default
961975
#(#write_values)*
976+
#(#write_skipped)*
962977
_serde::__private::Ok(())
963978
}
964979
}

0 commit comments

Comments
 (0)