Skip to content

Commit 53535d5

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 f38da85 commit 53535d5

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, cattrs, 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
}
@@ -883,15 +891,9 @@ fn read_fields_in_order_in_place(
883891
let expecting = cattrs.expecting().unwrap_or(&expecting);
884892

885893
let mut index_in_seq = 0usize;
886-
let write_values = fields.iter().map(|field| {
887-
let member = &field.member;
888-
889-
if field.attrs.skip_deserializing() {
890-
let default = Expr(expr_is_missing(field, cattrs));
891-
quote! {
892-
self.place.#member = #default;
893-
}
894-
} else {
894+
let write_values = fields.iter().filter_map(|field| {
895+
if !field.attrs.skip_deserializing() {
896+
let member = &field.member;
895897
let value_if_none = expr_is_missing_seq(Some(quote!(self.place.#member = )), index_in_seq, field, cattrs, expecting);
896898
let write = match field.attrs.deserialize_with() {
897899
None => {
@@ -919,8 +921,20 @@ fn read_fields_in_order_in_place(
919921
}
920922
};
921923
index_in_seq += 1;
922-
write
924+
return Some(write);
923925
}
926+
None
927+
});
928+
let write_skipped = fields.iter().filter_map(|field| {
929+
if field.attrs.skip_deserializing() {
930+
let member = &field.member;
931+
let default = Expr(expr_is_missing(field, cattrs));
932+
933+
return Some(quote! {
934+
self.place.#member = #default;
935+
});
936+
}
937+
None
924938
});
925939

926940
let this_type = &params.this_type;
@@ -942,6 +956,7 @@ fn read_fields_in_order_in_place(
942956
quote_block! {
943957
#let_default
944958
#(#write_values)*
959+
#(#write_skipped)*
945960
_serde::__private::Ok(())
946961
}
947962
}

0 commit comments

Comments
 (0)