Repository navigation
GH-47752: [C++][Python][Parquet] Add minimum compression savings for V2 pages - #52580
MashrafeeAryan wants to merge 9 commits into
Conversation
|
|
|
|
Add min_space_savings to control how much space compression must save. V2 pages below the threshold are written uncompressed. Keep the default behavior and V1 pages unchanged.
Add an option to choose how much space compression must save when writing Parquet files from Python. Add tests as well.
Dataset writing ignored min_space_savings. Move the argument to the end of the call so it reaches the writer. Add a test to check that the setting changes the file size.
|
|
65825cc to
89bf1b2
Compare
There was a problem hiding this comment.
This looks great @MashrafeeAryan!
I left some inline comments, noting major.
Besides addressing the linter errors, we should update the Python docs. A new option is added to write_table, ParquetWriter, write_to_dataset and ParquetFileWriteOptions. We should update _parquet_writer_arg_docs in python/pyarrow/parquet/core.py and the data-page-V2 paragraph in docs/source/cpp/parquet.rst.
Throw an error when users set min_space_savings for V1 pages. Update C++ and Python tests.
Require compressed data to be smaller, even when min_space_savings is 0.0. Simplify the compression check and update the test.
Check min_space_savings when users set it. Update the test and Python error handling.
Check compressed and original sizes in the existing test. Keep checking that the data reads back correctly.
Explain min_space_savings in the Python and C++ docs.
Fix spacing and line wrapping in the C++ changes.
| return this; | ||
| } | ||
|
|
||
| /// Used to set minimum threshold for V2 page data values compression |
There was a problem hiding this comment.
Perhaps?
| /// Used to set minimum threshold for V2 page data values compression | |
| /// Used to set minimum compression ration threshold for V2 page data values compression |
|
Doc issue appears to be from wrong ordering in
|
| else: | ||
| assert column.total_compressed_size < column.total_uncompressed_size | ||
|
|
||
|
|
There was a problem hiding this comment.
How about a threshold test too? Note this requires adding a random import.
| def _v2_column_chunk(table, **options): | |
| sink = pa.BufferOutputStream() | |
| pq.write_table(table, sink, compression="snappy", use_dictionary=False, | |
| data_page_version="2.0", **options) | |
| return pq.ParquetFile(sink.getvalue()).metadata.row_group(0).column(0) | |
| def test_min_space_savings_threshold(): | |
| rng = random.Random(42) | |
| values = [rng.randrange(16) for _ in range(1000)] | |
| table = pa.table({"v": pa.array(values, pa.int32())}) | |
| base = _v2_column_chunk(table) | |
| savings = 1 - base.total_compressed_size / base.total_uncompressed_size | |
| assert 0.1 < savings < 0.9 | |
| kept = _v2_column_chunk(table, min_space_savings=savings - 0.05) | |
| assert kept.total_compressed_size == base.total_compressed_size | |
| dropped = _v2_column_chunk(table, min_space_savings=savings + 0.05) | |
| assert dropped.total_compressed_size == dropped.total_uncompressed_size | |
| assert dropped.compression == "SNAPPY" |
|
@MashrafeeAryan this is looking good, some minor suggestions from me, but I think it's ready for another reviewer. Feel free to take it out of draft. @pitrou could we ask you for a review here? |
Fixes #47752.
Rationale for this change
Parquet's V2 pages currently keep compression whenever the compressed values are smaller than the original values. Even if it saves very little space, it still does it. For instance, it can compress 100 KB to 99 KB and save it. Even though that's 1% storage efficient, it might not be worth the decompression overhead while reading the file.
What changes are included in this PR?
In the PR, I added an optional
min_space_savingssetting between0.0and1.0. It gives users an option to select the minimum threshold to compress V2 page data values. For instance, if the original file is100 KBand the user hasmin_space_savings = 0.1, it means the compressed file needs to save at least 10% space. As a result, unless the file is<= 90 KB, it won't get saved.I keep the current behavior when the user does not set
min_space_savings.Added C++ and Python implementation.
Are these changes tested?
Are there any user-facing changes?
C++ and Python users can set
min_space_savingswhen writing V2 pages. For example,0.1requires at least 10% space savings before keeping compression.Was AI used for this PR?
ChatGPT helped to set up the build for PyArrow.
Codex helped find a bug in dataset_writing which ignored min_space_savings.
PR code and description written by:
Reviewed before submission by: