@@ -729,6 +729,28 @@ fn struct_field_should_encode[T](field_info EncoderFieldInfo, val T) bool {
729729 return true
730730}
731731
732+ // encode_struct_field_key keeps the non-type-specific part of struct field
733+ // encoding out of the comptime field loop. Otherwise every field gets its own
734+ // copy of the key-collision scan and key selection code.
735+ @[noinline]
736+ fn (mut encoder Encoder) encode_struct_field_key (mut used_keys []string , old_used_keys []string , prefix string , field_info EncoderFieldInfo, is_first bool ) bool {
737+ if field_info.key_name in old_used_keys {
738+ return encoder.encode_object_key (is_first, prefix + field_info.key_name)
739+ }
740+ used_keys << field_info.key_name
741+ return encoder.encode_object_key (is_first, field_info.key_name)
742+ }
743+
744+ @[noinline]
745+ fn (mut encoder Encoder) encode_embedded_struct_field_key (mut used_keys []string , reserved_keys []string , prefix string , field_info EncoderFieldInfo, is_first bool ) bool {
746+ should_prefix := field_info.key_name in used_keys || field_info.key_name in reserved_keys
747+ json_key := if should_prefix { prefix + field_info.key_name } else { field_info.key_name }
748+ if ! should_prefix {
749+ used_keys << field_info.key_name
750+ }
751+ return encoder.encode_object_key (is_first, json_key)
752+ }
753+
732754@[unsafe ]
733755fn (mut encoder Encoder) encode_struct_with_embeds [T](val T) {
734756 encoder.output << `{`
@@ -772,27 +794,17 @@ fn (mut encoder Encoder) encode_struct_fields[T](val T, was_first bool, old_used
772794 write_field = struct_field_should_encode (field_info, field_value)
773795
774796 if write_field {
775- if field_info.key_name in old_used_keys {
776- is_first = encoder.encode_object_key (is_first, prefix +
777- field_info.key_name)
778- } else {
779- is_first = encoder.encode_object_key (is_first, field_info.key_name)
780- used_keys << field_info.key_name
781- }
797+ is_first = encoder.encode_struct_field_key (mut used_keys, old_used_keys,
798+ prefix, field_info, is_first)
782799 encoder.encode_struct_field_value (field_value)
783800 }
784801 }
785802 } $else {
786803 write_field = struct_field_should_encode (field_info, val.$(field.name))
787804
788805 if write_field {
789- if field_info.key_name in old_used_keys {
790- is_first = encoder.encode_object_key (is_first, prefix +
791- field_info.key_name)
792- } else {
793- is_first = encoder.encode_object_key (is_first, field_info.key_name)
794- used_keys << field_info.key_name
795- }
806+ is_first = encoder.encode_struct_field_key (mut used_keys, old_used_keys,
807+ prefix, field_info, is_first)
796808 encoder.encode_struct_field_value (val.$(field.name))
797809 }
798810 }
@@ -858,34 +870,16 @@ fn (mut encoder Encoder) encode_embedded_struct_fields[T](val T, was_first bool,
858870 rlock field_value {
859871 write_field = struct_field_should_encode (field_info, field_value)
860872 if write_field {
861- should_prefix := field_info.key_name in used_keys
862- || field_info.key_name in reserved_keys
863- json_key := if should_prefix {
864- prefix + field_info.key_name
865- } else {
866- field_info.key_name
867- }
868- is_first = encoder.encode_object_key (is_first, json_key)
869- if ! should_prefix {
870- used_keys << field_info.key_name
871- }
873+ is_first = encoder.encode_embedded_struct_field_key (mut used_keys,
874+ reserved_keys, prefix, field_info, is_first)
872875 encoder.encode_struct_field_value (field_value)
873876 }
874877 }
875878 } $else {
876879 write_field = struct_field_should_encode (field_info, val.$(field.name))
877880 if write_field {
878- should_prefix := field_info.key_name in used_keys
879- || field_info.key_name in reserved_keys
880- json_key := if should_prefix {
881- prefix + field_info.key_name
882- } else {
883- field_info.key_name
884- }
885- is_first = encoder.encode_object_key (is_first, json_key)
886- if ! should_prefix {
887- used_keys << field_info.key_name
888- }
881+ is_first = encoder.encode_embedded_struct_field_key (mut used_keys,
882+ reserved_keys, prefix, field_info, is_first)
889883 encoder.encode_struct_field_value (val.$(field.name))
890884 }
891885 }
0 commit comments