Repository: apache/arrow
Pull request #45793: GH-45792: [C++] Add benchmarks to Meson configuration
Author: login: WillAyd
Labels: name: Component: C++
name: awaiting merge
description: Awaiting merge
Created: 2025-03-14T17:40:42Z | Merged: 2025-03-16T02:13:51Z

### Rationale for this change

This makes it possible to add benchmarks to the Meson configuration

### What changes are included in this PR?

Benchmarks from the top level configuration are added

### Are these changes tested?

Locally yes. To do so, simply:

```sh
meson setup builddir -Dbenchmarks=true
meson test -C builddir --benchmark 
```

### Are there any user-facing changes?
No
* GitHub Issue: #45792


Diff:
diff --git a/cpp/meson.build b/cpp/meson.build
index e5a30b0eb41e..a82ce3985726 100644
--- a/cpp/meson.build
+++ b/cpp/meson.build
@@ -56,11 +56,12 @@ if git_description == ''
     git_description = run_command('git', 'describe', '--tags', check: false).stdout().strip()
 endif
 
+needs_benchmarks = get_option('benchmarks')
 needs_filesystem = false
 needs_integration = false
 needs_tests = get_option('tests')
-needs_ipc = get_option('ipc') or needs_tests
-needs_testing = get_option('testing') or needs_tests
+needs_ipc = get_option('ipc') or needs_tests or needs_benchmarks
+needs_testing = get_option('testing') or needs_tests or needs_benchmarks
 needs_json = get_option('json') or needs_testing
 
 subdir('src/arrow')
diff --git a/cpp/meson.options b/cpp/meson.options
index 8c120b12eab3..87b20bbbe211 100644
--- a/cpp/meson.options
+++ b/cpp/meson.options
@@ -15,6 +15,13 @@
 # specific language governing permissions and limitations
 # under the License.
 
+option(
+    'benchmarks',
+    type: 'boolean',
+    description: 'Build the Arrow micro benchmarks',
+    value: false,
+)
+
 option(
     'ipc',
     type: 'boolean',
diff --git a/cpp/src/arrow/meson.build b/cpp/src/arrow/meson.build
index 3a538ca2b2a3..3f30b6b66635 100644
--- a/cpp/src/arrow/meson.build
+++ b/cpp/src/arrow/meson.build
@@ -355,7 +355,7 @@ install_headers(
     install_dir: 'arrow',
 )
 
-if needs_tests
+if needs_testing
     filesystem_dep = dependency(
         'boost',
         modules: ['filesystem'],
@@ -440,13 +440,44 @@ if needs_ipc
     }
 endif
 
-foreach key, val : arrow_tests
+if needs_tests
+    foreach key, val : arrow_tests
+        exc = executable(
+            key,
+            sources: val['sources'],
+            dependencies: [arrow_test_dep, val.get('dependencies', [])],
+        )
+        test(key, exc)
+    endforeach
+endif
+
+if needs_benchmarks
+    benchmark_dep = dependency(
+        'benchmark',
+        default_options: {'tests': 'disabled'},
+    )
+else
+    benchmark_dep = disabler()
+endif
+
+arrow_benchmarks = [
+    'builder_benchmark',
+    'chunk_resolver_benchmark',
+    'compare_benchmark',
+    'memory_pool_benchmark',
+    'type_benchmark',
+    'tensor_benchmark',
+]
+
+foreach benchmark : arrow_benchmarks
+    benchmark_name = 'arrow-@0@'.format(benchmark.replace('_', '-'))
     exc = executable(
-        key,
-        sources: val['sources'],
-        dependencies: [arrow_test_dep, val.get('dependencies', [])],
+        benchmark_name,
+        sources: '@0@.cc'.format(benchmark),
+        dependencies: [arrow_test_dep, benchmark_dep],
     )
-    test(key, exc)
+
+    benchmark(benchmark_name, exc)
 endforeach
 
 version = meson.project_version()
diff --git a/cpp/subprojects/google-benchmark.wrap b/cpp/subprojects/google-benchmark.wrap
new file mode 100644
index 000000000000..3b6704639e7a
--- /dev/null
+++ b/cpp/subprojects/google-benchmark.wrap
@@ -0,0 +1,31 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[wrap-file]
+directory = benchmark-1.8.4
+source_url = https://github.com/google/benchmark/archive/refs/tags/v1.8.4.tar.gz
+source_filename = benchmark-1.8.4.tar.gz
+source_hash = 3e7059b6b11fb1bbe28e33e02519398ca94c1818874ebed18e504dc6f709be45
+patch_filename = google-benchmark_1.8.4-1_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/google-benchmark_1.8.4-1/get_patch
+patch_hash = 77cdae534fe12b6783c1267de3673d3462b229054519034710d581b419e73cca
+source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/google-benchmark_1.8.4-1/benchmark-1.8.4.tar.gz
+wrapdb_version = 1.8.4-1
+
+[provide]
+benchmark = google_benchmark_dep
+benchmark-main = google_benchmark_main_dep


Reviews:
user: login: kou
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-15T05:43:22Z
user: login: WillAyd
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-15T18:09:33Z
user: login: kou
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-16T02:12:56Z
user: login: kou
body: +1
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-16T02:13:42Z

Review comments:
diff_hunk: @@ -440,13 +440,44 @@ if needs_ipc
     }
 endif
 
-foreach key, val : arrow_tests
+if needs_tests
+    foreach key, val : arrow_tests
+        exc = executable(
+            key,
+            sources: val['sources'],
+            dependencies: [arrow_test_dep, val.get('dependencies', [])],
+        )
+        test(key, exc)
+    endforeach
+endif
+
+if needs_benchmarks
+    benchmark_dep = dependency(
+        'benchmark',
+        default_options: {'tests': 'disabled'},
+    )
+else
+    benchmark_dep = disabler()
+endif
+
+arrow_benchmarks = [
+    'builder_benchmark',
+    'chunk_resolver_benchmark',
+    'compare_benchmark',
+    'memory_pool_benchmark',
+    'type_benchmark',
+    'tensor_benchmark',
+]
+
+foreach benchmark : arrow_benchmarks
path: cpp/src/arrow/meson.build
user: login: kou
body: Do we need `if needs_benchmarks` here?
created_at: 2025-03-15T05:42:56Z
author_association: MEMBER
diff_hunk: @@ -440,13 +440,44 @@ if needs_ipc
     }
 endif
 
-foreach key, val : arrow_tests
+if needs_tests
+    foreach key, val : arrow_tests
+        exc = executable(
+            key,
+            sources: val['sources'],
+            dependencies: [arrow_test_dep, val.get('dependencies', [])],
+        )
+        test(key, exc)
+    endforeach
+endif
+
+if needs_benchmarks
+    benchmark_dep = dependency(
+        'benchmark',
+        default_options: {'tests': 'disabled'},
+    )
+else
+    benchmark_dep = disabler()
+endif
+
+arrow_benchmarks = [
+    'builder_benchmark',
+    'chunk_resolver_benchmark',
+    'compare_benchmark',
+    'memory_pool_benchmark',
+    'type_benchmark',
+    'tensor_benchmark',
+]
+
+foreach benchmark : arrow_benchmarks
path: cpp/src/arrow/meson.build
user: login: WillAyd
body: It wouldn't hurt but it is not necessary. Because that check is done on L454-L461, if the option is not set there then the `benchmark_dep` will be set to the Meson disabler() object. Since that is used as a dependency here, it will automatically skip building these targets if it is disabled.

The gist of the disabler() object is that it prevents you from having to add a lot of `if <option>` checks in your code. But if that is confusing we can stick with the more traditional pattern
created_at: 2025-03-15T18:09:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -440,13 +440,44 @@ if needs_ipc
     }
 endif
 
-foreach key, val : arrow_tests
+if needs_tests
+    foreach key, val : arrow_tests
+        exc = executable(
+            key,
+            sources: val['sources'],
+            dependencies: [arrow_test_dep, val.get('dependencies', [])],
+        )
+        test(key, exc)
+    endforeach
+endif
+
+if needs_benchmarks
+    benchmark_dep = dependency(
+        'benchmark',
+        default_options: {'tests': 'disabled'},
+    )
+else
+    benchmark_dep = disabler()
+endif
+
+arrow_benchmarks = [
+    'builder_benchmark',
+    'chunk_resolver_benchmark',
+    'compare_benchmark',
+    'memory_pool_benchmark',
+    'type_benchmark',
+    'tensor_benchmark',
+]
+
+foreach benchmark : arrow_benchmarks
path: cpp/src/arrow/meson.build
user: login: kou
body: OK. Let's keep this style.
created_at: 2025-03-16T02:12:56Z
author_association: MEMBER

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-14T17:41:11Z
body: :warning: GitHub issue #45792 **has been automatically assigned in GitHub** to PR creator.
author_association: NONE
user: login: kou
created_at: 2025-03-15T05:43:37Z
body: @github-actions crossbow submit *meson
author_association: MEMBER
user: login: github-actions[bot]
created_at: 2025-03-15T05:45:44Z
body: Revision: 50aa003a669aa5b5691962aeb7de1da3b5975517

Submitted crossbow builds: [ursacomputing/crossbow @ actions-d6dd6bd8b5](https://github.com/ursacomputing/crossbow/branches/all?query=actions-d6dd6bd8b5)

|Task|Status|
|----|------|
|test-conda-cpp-meson|[![GitHub Actions](https://github.com/ursacomputing/crossbow/actions/workflows/crossbow.yml/badge.svg?branch=actions-d6dd6bd8b5-github-test-conda-cpp-meson)](https://github.com/ursacomputing/crossbow/actions/runs/13870020343/job/38815448626)|
author_association: NONE
user: login: conbench-apache-arrow[bot]
created_at: 2025-03-16T08:52:53Z
body: After merging your PR, Conbench analyzed the 4 benchmarking runs that have been run so far on merge-commit aac110d4ef105c671ff5f9224effd53ed629aa8a.

There were no benchmark performance regressions. 🎉

The [full Conbench report](https://github.com/apache/arrow/runs/38841139652) has more details. It also includes information about 7 possible false positives for unstable benchmarks that are known to sometimes produce them.
author_association: NONE