arrow: Reading FixedSizeList from parquet is slower than reading values into more rows
Describe the bug, including details regarding any error messages, version, and platform.
I’m not 100% sure if it’s a bug, but I don’t understand the differences between the two cases: Nested arrays:
table with 30 columns, 2 level "index" (so 2 columns) and 29 FixedSizeList<double, 80> columns, 100k rows
Exploded:
table with 31 columns, 3 level "index" (so 3 columns) and 29 double columns, 8000k rows
Reading the first table from parquet (version 2.6, zstd compression, single file) is surprisingly slower than reading the second table. I’d assume it’s the same task, a few columns are even shorter. The file sizes are almost equal.
I used pyarrow 11 from conda and local SSD.
Component(s)
Parquet Python
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 16 (16 by maintainers)
The paper they link to actually explains why the approach is problematic - http://arxiv.org/pdf/1209.2137v5.pdf. The whole paper is on why not to implement delta compression in this way 😂
We don’t support FixedSizeList in arrow-rs AFAIK. Parquet to my knowledge does not have an equivalent logical construct, and so it isn’t particularly clear to me what support would mean other than implicitly casting between a regular list and a fixed size list.
Assuming the doubles are PLAIN encoded this is not surprising to me, you are comparing the performance of what is effectively a
memcpy
that will run at the memory bandwidth, to a fairly complex bit-packing scheme used for the definition and repetition levels.In the Rust implementation we have a couple of tricks that help here, but it is still relatively expensive (at least compared to primitive decoding):
It will actually all be 2, unless the doubles are themselves not nullable
These repetition levels will be RLE encoded. Theoretically a reader could preserve this, but the record shredding logic is extremely fiddly and so might run the risk of adding complexity to an already very complex piece of code. At least in arrow-rs we always decode repetition levels to an array of
i16
Yes, in the future, developer may optimize it. If
FixedSizeArray
is non-nullable, Parquet can have a single static value, but ifFixedSizeArray
is non-nullable, it cannot.I’ve profile the C++ part, in my MacOS with release (O2):
The benchmark uses list rather than FixedSizeList, but I think the benchmark is similiar.
I’m not so familiar with Python part, maybe someone can profile that path
The same happens with not null values (I’m not sure how to define the not null list correctly, but looks like it doesn’t matter):
%%timeit
%%timeit
%%timeit