Skip to content

WIP: Test DataFusion with experimental IncrementalRecordBatchBuilder #16208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from

Conversation

alamb
Copy link
Contributor

@alamb alamb commented May 29, 2025

This PR is for testing DataFusion with the code in the following PR

I want to run 2 experiments:

  1. Does using IncremntalRecordBatchBuilder in Filter help
  2. Is ClickBench performance better with filter_pushdown enabled (WIP: Test DataFusion with experimental Parquet Filter Pushdown #16222)

If I can see significant improvements I will proceed to making apache/arrow-rs#7513 real

@github-actions github-actions bot added the physical-plan Changes to the physical-plan crate label May 29, 2025
@alamb
Copy link
Contributor Author

alamb commented May 29, 2025

🤖 ./gh_compare_branch.sh Benchmark Script Running
Linux aal-dev 6.11.0-1013-gcp #13~24.04.1-Ubuntu SMP Wed Apr 2 16:34:16 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing alamb/test_filter_pushdown (f9dbcc0) to 7002a00 diff
Benchmarks: tpch_mem clickbench_partitioned clickbench_extended
Results will be posted here when complete

@alamb
Copy link
Contributor Author

alamb commented May 29, 2025

🤖: Benchmark completed

Details

Comparing HEAD and alamb_test_filter_pushdown
--------------------
Benchmark clickbench_extended.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Query        ┃       HEAD ┃ alamb_test_filter_pushdown ┃       Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ QQuery 0     │  1822.08ms │                  1950.22ms │ 1.07x slower │
│ QQuery 1     │   686.15ms │                   725.22ms │ 1.06x slower │
│ QQuery 2     │  1421.43ms │                  1437.38ms │    no change │
│ QQuery 3     │   684.69ms │                   705.23ms │    no change │
│ QQuery 4     │  1456.23ms │                  1479.06ms │    no change │
│ QQuery 5     │ 15371.83ms │                 15471.55ms │    no change │
│ QQuery 6     │  2033.56ms │                  2057.13ms │    no change │
│ QQuery 7     │  2091.87ms │                  2101.95ms │    no change │
│ QQuery 8     │   849.28ms │                   854.59ms │    no change │
└──────────────┴────────────┴────────────────────────────┴──────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                         ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                         │ 26417.11ms │
│ Total Time (alamb_test_filter_pushdown)   │ 26782.33ms │
│ Average Time (HEAD)                       │  2935.23ms │
│ Average Time (alamb_test_filter_pushdown) │  2975.81ms │
│ Queries Faster                            │          0 │
│ Queries Slower                            │          2 │
│ Queries with No Change                    │          7 │
└───────────────────────────────────────────┴────────────┘
--------------------
Benchmark clickbench_partitioned.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query        ┃       HEAD ┃ alamb_test_filter_pushdown ┃        Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 0     │    15.73ms │                    14.77ms │ +1.06x faster │
│ QQuery 1     │    31.94ms │                    32.66ms │     no change │
│ QQuery 2     │    80.09ms │                    79.35ms │     no change │
│ QQuery 3     │    98.77ms │                    95.13ms │     no change │
│ QQuery 4     │   605.02ms │                   602.99ms │     no change │
│ QQuery 5     │   868.32ms │                   856.53ms │     no change │
│ QQuery 6     │    23.87ms │                    23.91ms │     no change │
│ QQuery 7     │    37.19ms │                    38.29ms │     no change │
│ QQuery 8     │   933.70ms │                   914.39ms │     no change │
│ QQuery 9     │  1279.67ms │                  1209.80ms │ +1.06x faster │
│ QQuery 10    │   272.21ms │                   273.11ms │     no change │
│ QQuery 11    │   308.41ms │                   298.73ms │     no change │
│ QQuery 12    │   930.67ms │                   910.59ms │     no change │
│ QQuery 13    │  1348.50ms │                  1369.46ms │     no change │
│ QQuery 14    │   860.32ms │                   844.04ms │     no change │
│ QQuery 15    │   843.03ms │                   821.28ms │     no change │
│ QQuery 16    │  1746.35ms │                  1729.29ms │     no change │
│ QQuery 17    │  1634.90ms │                  1603.86ms │     no change │
│ QQuery 18    │  3126.70ms │                  3105.76ms │     no change │
│ QQuery 19    │    84.55ms │                    81.44ms │     no change │
│ QQuery 20    │  1152.02ms │                  1247.44ms │  1.08x slower │
│ QQuery 21    │  1340.97ms │                  1376.02ms │     no change │
│ QQuery 22    │  2221.77ms │                  2373.59ms │  1.07x slower │
│ QQuery 23    │  8067.48ms │                  8453.86ms │     no change │
│ QQuery 24    │   472.64ms │                   465.06ms │     no change │
│ QQuery 25    │   396.53ms │                   398.05ms │     no change │
│ QQuery 26    │   535.55ms │                   536.82ms │     no change │
│ QQuery 27    │  1576.77ms │                  1702.88ms │  1.08x slower │
│ QQuery 28    │ 12485.75ms │                 13253.81ms │  1.06x slower │
│ QQuery 29    │   530.72ms │                   528.47ms │     no change │
│ QQuery 30    │   802.59ms │                   834.59ms │     no change │
│ QQuery 31    │   841.57ms │                   875.02ms │     no change │
│ QQuery 32    │  2642.67ms │                  2824.64ms │  1.07x slower │
│ QQuery 33    │  3355.69ms │                  3530.76ms │  1.05x slower │
│ QQuery 34    │  3376.55ms │                  3486.38ms │     no change │
│ QQuery 35    │  1301.55ms │                  1325.71ms │     no change │
│ QQuery 36    │   123.82ms │                   122.70ms │     no change │
│ QQuery 37    │    53.99ms │                    56.54ms │     no change │
│ QQuery 38    │   125.95ms │                   123.57ms │     no change │
│ QQuery 39    │   201.77ms │                   202.62ms │     no change │
│ QQuery 40    │    48.41ms │                    45.65ms │ +1.06x faster │
│ QQuery 41    │    44.89ms │                    42.66ms │     no change │
│ QQuery 42    │    38.23ms │                    37.99ms │     no change │
└──────────────┴────────────┴────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                         ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                         │ 56867.78ms │
│ Total Time (alamb_test_filter_pushdown)   │ 58750.22ms │
│ Average Time (HEAD)                       │  1322.51ms │
│ Average Time (alamb_test_filter_pushdown) │  1366.28ms │
│ Queries Faster                            │          3 │
│ Queries Slower                            │          6 │
│ Queries with No Change                    │         34 │
└───────────────────────────────────────────┴────────────┘
--------------------
Benchmark tpch_mem_sf1.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Query        ┃     HEAD ┃ alamb_test_filter_pushdown ┃       Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ QQuery 1     │ 118.31ms │                   122.73ms │    no change │
│ QQuery 2     │  22.51ms │                    24.80ms │ 1.10x slower │
│ QQuery 3     │  34.20ms │                    40.26ms │ 1.18x slower │
│ QQuery 4     │  19.66ms │                    23.27ms │ 1.18x slower │
│ QQuery 5     │  51.95ms │                    55.75ms │ 1.07x slower │
│ QQuery 6     │  12.14ms │                    13.35ms │ 1.10x slower │
│ QQuery 7     │  96.38ms │                    95.26ms │    no change │
│ QQuery 8     │  25.57ms │                    27.32ms │ 1.07x slower │
│ QQuery 9     │  58.54ms │                    59.67ms │    no change │
│ QQuery 10    │  56.38ms │                    60.19ms │ 1.07x slower │
│ QQuery 11    │  11.69ms │                    12.14ms │    no change │
│ QQuery 12    │  43.32ms │                    46.02ms │ 1.06x slower │
│ QQuery 13    │  27.50ms │                    29.77ms │ 1.08x slower │
│ QQuery 14    │   9.93ms │                    10.49ms │ 1.06x slower │
│ QQuery 15    │  23.00ms │                    24.50ms │ 1.07x slower │
│ QQuery 16    │  21.28ms │                    21.87ms │    no change │
│ QQuery 17    │  96.01ms │                    98.92ms │    no change │
│ QQuery 18    │ 208.85ms │                   218.36ms │    no change │
│ QQuery 19    │  26.14ms │                    28.99ms │ 1.11x slower │
│ QQuery 20    │  35.76ms │                    36.81ms │    no change │
│ QQuery 21    │ 158.51ms │                   164.05ms │    no change │
│ QQuery 22    │  16.23ms │                    16.65ms │    no change │
└──────────────┴──────────┴────────────────────────────┴──────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary                         ┃           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD)                         │ 1173.85ms │
│ Total Time (alamb_test_filter_pushdown)   │ 1231.17ms │
│ Average Time (HEAD)                       │   53.36ms │
│ Average Time (alamb_test_filter_pushdown) │   55.96ms │
│ Queries Faster                            │         0 │
│ Queries Slower                            │        12 │
│ Queries with No Change                    │        10 │
└───────────────────────────────────────────┴───────────┘

@alamb
Copy link
Contributor Author

alamb commented May 29, 2025

🤖: Benchmark completed

Hmm that is somewhat depressing. I will investigate tomorrow

@zhuqi-lucas
Copy link
Contributor

Interesting, i am confused why it's different from arrow-rs clickbench result.

@zhuqi-lucas
Copy link
Contributor

zhuqi-lucas commented May 30, 2025

Ok, i misunderstood this testing is not for parquet filter pushdown enabled...

This is Does using IncremntalRecordBatchBuilder in Filter help

.output_batch_builder
.as_mut()
.expect("output_batch_builder should be Some");
Ok(output_batch_builder.append_filtered(batch, filter)?)
Copy link
Contributor

@Dandandan Dandandan May 30, 2025

Choose a reason for hiding this comment

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

I expect it should be faster rather than incrementally build a new batch based on a number of arrays, to first evaluate a number of filters (self.predicate.evaluate(&batch) until the number of true values reaches the target batch size and then have a filter api to filter a list of batches. This avoids reallocations / copying as the target capacity can be calculated.
In order to avoid buffering too much batches probably have to limit this / create a batch anyway after x batches or having x megabytes in memory.

Copy link
Contributor

Choose a reason for hiding this comment

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

My feeling is this should to do this "multi batch filter" and then concat anyway if smaller batches are generated by this approach, rather than using a builder approach.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This avoids reallocations / copying as the target capacity can be calculated.
In order to avoid buffering too much batches probably have to limit this / create a batch anyway after x batches or having x megabytes in memory.

I was trying to avoid having any reallocations in the IncrementalRecordBatchBuilder -- since we know the target output batch size (batch_size) it knows how much space each batch will take up front and can just straight up allocate it ( instantiate_builder function creates the builders with with_capacity)

However, now that I think about it, after a call to finish() the updated builder doesn't have the right allocation 🤔

I'll look into that more later today

Copy link
Contributor

@Dandandan Dandandan May 30, 2025

Choose a reason for hiding this comment

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

space each batch will take up front and can just straight up allocate

Hm yeah with primitive and views this might be okay - we might have to test other data sources though (with normal binary types were it can't be preallocated).

@alamb alamb changed the title WIP: Test DataFusion with experimental parquet pushdown WIP: Test DataFusion with experimental IncrementalRecordBatchBuilder Jun 1, 2025
@alamb
Copy link
Contributor Author

alamb commented Jun 1, 2025

I ran q24 locally and did see a small slowdown and did some profiling

As expected filtering is about 30% of the overall execution time of the filtering time, about 1/2 goes to creating the output
Screenshot 2025-06-01 at 7 20 04 AM

The analysis reveals some more places to potentially improve (also aligned with @Dandandan 's suggestions):
Screenshot 2025-06-01 at 7 24 41 AM

There is also some evidence of reallocation as @Dandandan mentions: #16208 (comment)
Screenshot 2025-06-01 at 7 29 29 AM

Next steps:

  1. I will also try and update the code to avoid allocations when possible (specifically, recreate builders)
  2. Optimize predicate creation some more (create it once / slice rather than twice)
Details

On this branch: alamb/test_filter_pushdown I do so

./datafusion-cli-alamb_test_filter_pushdown
 -f q24-many.sql | grep Elapsed
Elapsed 0.258 seconds.
Elapsed 0.237 seconds.
Elapsed 0.220 seconds.
Elapsed 0.213 seconds.
Elapsed 0.223 seconds.
Elapsed 0.225 seconds.
Elapsed 0.223 seconds.
Elapsed 0.219 seconds.
Elapsed 0.223 seconds.

On main main

datafusion-cli -f q24-many.sql | grep Elapsed
Elapsed 0.220 seconds.
Elapsed 0.217 seconds.
Elapsed 0.203 seconds.
Elapsed 0.211 seconds.
Elapsed 0.216 seconds.
Elapsed 0.197 seconds.
Elapsed 0.203 seconds.
Elapsed 0.199 seconds.
Elapsed 0.218 seconds.

@alamb
Copy link
Contributor Author

alamb commented Jun 4, 2025

Closing in favor of #16249

@alamb alamb closed this Jun 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
physical-plan Changes to the physical-plan crate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants