Skip to content

Conversation

@Weijun-H
Copy link
Member

@Weijun-H Weijun-H commented Jan 2, 2026

Which issue does this PR close?

  • Closes #NNN.

Rationale for this change

Optimize JSON struct decoding on wide objects by reducing per-row allocations and repeated field lookups.

What changes are included in this PR?

Reuse a flat child-position buffer in StructArrayDecoder and add an optional field-name index for object mode.
Skip building the field-name index for list mode; add overflow/allocation checks.

decode_wide_object_i64_json
                        time:   [11.828 ms 11.865 ms 11.905 ms]
                        change: [−67.828% −67.378% −67.008%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
  2 (2.00%) high mild
  1 (1.00%) high severe

decode_wide_object_i64_serialize
                        time:   [7.6923 ms 7.7402 ms 7.7906 ms]
                        change: [−75.652% −75.483% −75.331%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 1 outliers among 100 measurements (1.00%)
  1 (1.00%) high mild

Are these changes tested?

Yes

Are there any user-facing changes?

No

@github-actions github-actions bot added the arrow Changes to the arrow crate label Jan 2, 2026
@Weijun-H Weijun-H marked this pull request as ready for review January 2, 2026 13:57
@Weijun-H Weijun-H changed the title perf: improve field indexing in StructArrayDecoder perf: improve field indexing in StructArrayDecoder (1.5x speed up) Jan 2, 2026
@Weijun-H Weijun-H changed the title perf: improve field indexing in StructArrayDecoder (1.5x speed up) perf: improve field indexing in StructArrayDecoder (2x speed up) Jan 2, 2026
@Weijun-H Weijun-H changed the title perf: improve field indexing in StructArrayDecoder (2x speed up) perf: improve field indexing in StructArrayDecoder (1.7x speed up) Jan 2, 2026
Copy link
Contributor

@scovich scovich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand the indexing code well enough to say whether that part is correct, but the idea of using an optional index for field name lookups makes a lot of sense to me.

}
}

fn build_field_index(fields: &Fields) -> Option<HashMap<String, usize>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qq: Do lifetimes coincide so that we could return Option<HashMap<&str, usize>> instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the lifetimes do coincide. we can use HashMap<&'a str, usize> by taking fields: &'a Fields as a parameter, which avoids the self-referential struct problem. However, this would require threading the lifetime parameter <'a> through the entire decoder system across many files. Since the lookup performance is identical, I don’t think it’s worth the added complexity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it would be a good follow on PR

Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Weijun-H and @scovich

use std::fmt::Write;
use std::sync::Arc;

fn build_schema(field_count: usize) -> Arc<Schema> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please add some comments here with an example of what this code does / what patterns of input it creates?

Also, it would help me to reproduce your results if you could make a separate PR with the benchmarks (so I can compare main to the PR)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

separate benchmark here

#9107

}
}

fn build_field_index(fields: &Fields) -> Option<HashMap<String, usize>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it would be a good follow on PR

@alamb alamb changed the title perf: improve field indexing in StructArrayDecoder (1.7x speed up) perf: improve field indexing in JSON StructArrayDecoder (1.7x speed up) Jan 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arrow Changes to the arrow crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants