This is an automated email from the ASF dual-hosted git repository.
kou pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/arrow-flight-sql-postgresql.git
The following commit(s) were added to refs/heads/main by this push:
new 56b165d Add benchmark for string (#168)
56b165d is described below
commit 56b165df77e2dd506ba09cc5a05648df99fd3f0c
Author: Sutou Kouhei <[email protected]>
AuthorDate: Mon Nov 13 22:23:46 2023 +0900
Add benchmark for string (#168)
Closes GH-153
`SELECT` pattern parses text representation result.
`COPY` pattern parses binary representation result.
Integer pattern is faster that PostgreSQL but string pattern is slower
than PostgreSQL because we need to copy data when we generate record
batches with Apache Arrow C++'s array builder. We will improve
performance by avoiding the copy.
---
benchmark/{integer => }/README.md | 75 ++--
benchmark/copy.c | 314 +++++++++++++++
benchmark/{integer => }/graph.rb | 24 +-
benchmark/integer/README.md | 55 +--
benchmark/integer/copy.c | 77 ----
benchmark/integer/prepare-100K.sql | 26 --
benchmark/integer/prepare-10M.sql | 26 --
benchmark/integer/prepare-1M.sql | 26 --
benchmark/integer/{graph.rb => prepare-sql.sh} | 34 +-
benchmark/integer/result.csv | 18 +-
benchmark/integer/result.svg | 241 ++++++-----
benchmark/markdown.rb | 77 ++++
benchmark/{integer => }/meson.build | 4 +-
benchmark/run.sh | 62 +++
benchmark/{integer => }/select-adbc-flight-sql.rb | 0
benchmark/{integer => }/select-adbc-postgresql.rb | 0
.../select-pandas.py | 20 +-
.../select-adbc-postgresql.rb => select-polars.py} | 32 +-
benchmark/{integer => }/select.c | 62 ++-
benchmark/{integer => }/select.rb | 5 +-
benchmark/{integer => }/select.sql | 0
benchmark/string/README.md | 59 +++
.../{integer/graph.rb => string/prepare-sql.sh} | 36 +-
benchmark/string/result.csv | 10 +
benchmark/{integer => string}/result.svg | 441 +++++++++++----------
dev/release/rat_exclude_files.txt | 4 +-
meson.build | 2 +-
27 files changed, 1120 insertions(+), 610 deletions(-)
diff --git a/benchmark/integer/README.md b/benchmark/README.md
similarity index 53%
copy from benchmark/integer/README.md
copy to benchmark/README.md
index 86fe02d..58c09ab 100644
--- a/benchmark/integer/README.md
+++ b/benchmark/README.md
@@ -17,7 +17,7 @@
under the License.
-->
-# Benchmark - only with integer data
+# Benchmark
## How to run
@@ -29,54 +29,59 @@ Run PostgreSQL with the following configuration:
shared_preload_libraries = 'arrow_flight_sql'
```
-Prepare database:
+Run the benchmark script:
```bash
-psql postgres -c '\i benchmark/integer/prepare-1M.sql'
+benchmark/run.sh
```
-It creates `afs_benchmark` database and `data` table in the database.
-It also inserts 10M records with random integers to the table.
+It runs all benchmarks and outputs their results to
+`benchmark/${BENCHMARK}/result.csv`.
-Run the following programs:
+You can visualize them:
-- `select.rb`: It uses Apache Arrow Flight SQL
-- `select`: It uses PostgreSQL's C API
-- `select.sql`: You need to use `psql` to run this
+```bash
+benchmark/graph.rb
+```
-All of them just run `SELECT * FROM data`.
+It generates `benchmark/${BENCHMARK}/result.svg`.
+
+You can format them as Markdown:
+
+```bash
+benchmark/markdown.rb
+```
-## Result
+It replaces benchmark results in `benchmark/${BENCHMARK}/README.md`.
-Here is a benchmark result on the following environment:
+### Details
-- OS: Debian GNU/Linux sid
-- CPU: AMD Ryzen 9 3900X 12-Core Processor
-- Memory: 64GiB
-- PostgreSQL: 16 (not released yet)
- 019f8624664dbf1e25e2bd721c7e99822812d109
-- Apache Arrow: 12.0.0-SNAPSHOT
- 237705bf17486cfc35ab7d1ddfe59dd60f042ab8
-- Apache Arrow Flight SQL PostgreSQL adapter:
- 0.1.0 (not released yet)
- 120e7bbd3fd580c892c988499d488c7e8b34efe2
+Each sub directory have a shell script that outputs preparation
+SQL. For example, you can use `benchmark/integer/prepare-sql.sh` for
+integer benchmark:
-
+```bash
+benchmark/integer/prepare-sql.sh 1000000 afs_benchmark | psql -d postgres
+```
-100K records:
+It creates `afs_benchmark` database and `data` table in the database.
+It also inserts 1000000 (1M) records with random integers to the
+table.
-| Apache Arrow Flight SQL | C | psql |
-| ----------------------- | ----- | ----- |
-| 0.014 | 0.012 | 0.011 |
+You can use the following programs to measure each approach:
-1M records:
+- `select.rb`: It uses Apache Arrow Flight SQL
+- `select-adbc-flight-sql.rb`: It uses Apache Arrow Flight SQL via ADBC
+- `select-adbc-postgresql.rb`: It uses PostgreSQL protocol via ADBC
+- `select-pandas.py`: It uses pandas
+- `select-polars.py`: It uses Polars
+- `select`: It uses PostgreSQL's C API
+- `select.sql`: You need to use `psql` to run this
+- `copy`: It uses `COPY` and PostgreSQL's C API
-| Apache Arrow Flight SQL | C | psql |
-| ----------------------- | ----- | ----- |
-| 0.069 | 0.116 | 0.107 |
+All of them just run `SELECT * FROM data`.
-10M records:
+## Results
-| Apache Arrow Flight SQL | C | psql |
-| ----------------------- | ----- | ----- |
-| 0.653 | 1.154 | 1.128 |
+- [integer](integer/README.md)
+- [string](string/README.md)
diff --git a/benchmark/copy.c b/benchmark/copy.c
new file mode 100644
index 0000000..11ad095
--- /dev/null
+++ b/benchmark/copy.c
@@ -0,0 +1,314 @@
+/*
+ * 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.
+ */
+
+#include <arpa/inet.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <libpq-fe.h>
+
+#include <catalog/pg_type_d.h>
+
+/* See the "Binary Format" section in
+ * https://www.postgresql.org/docs/current/sql-copy.html for
+ * details. */
+static const char signature[] = "PGCOPY\n\377\r\n";
+/* The last '\0' is also part of the signature. */
+static const size_t signatureSize = sizeof(signature);
+
+typedef struct {
+ char* data;
+ size_t size;
+} Buffer;
+
+static bool
+read_uint16(Buffer* buffer, uint16_t* output, const char* tag)
+{
+ if (buffer->size < sizeof(uint16_t))
+ {
+ fprintf(stderr,
+ "%s: can't read uint16_t (%d bytes) value: %d",
+ tag,
+ (int)sizeof(uint16_t),
+ (int)(buffer->size));
+ return false;
+ }
+
+ *output = htons(*((uint16_t*)(buffer->data)));
+ buffer->data += sizeof(uint16_t);
+ buffer->size -= sizeof(uint16_t);
+ return true;
+}
+
+static bool
+read_uint32(Buffer* buffer, uint32_t* output, const char* tag)
+{
+ if (buffer->size < sizeof(uint32_t))
+ {
+ fprintf(stderr,
+ "%s: can't read uint32_t (%d bytes) value: %d",
+ tag,
+ (int)sizeof(uint32_t),
+ (int)(buffer->size));
+ return false;
+ }
+
+ *output = htonl(*((uint32_t*)(buffer->data)));
+ buffer->data += sizeof(uint32_t);
+ buffer->size -= sizeof(uint32_t);
+ return true;
+}
+
+static bool
+parse_header(Buffer* buffer)
+{
+ uint32_t flags;
+ uint32_t extensionLength;
+
+ if (buffer->size < signatureSize)
+ {
+ fprintf(stderr,
+ "Signature (%d bytes) doesn't exist: %d",
+ (int)signatureSize,
+ (int)(buffer->size));
+ return false;
+ }
+ if (memcmp(buffer->data, signature, signatureSize) != 0)
+ {
+ fprintf(stderr, "Wrong signature: <%.*s>", (int)signatureSize,
buffer->data);
+ return false;
+ }
+ buffer->data += signatureSize;
+ buffer->size -= signatureSize;
+
+ if (!read_uint32(buffer, &flags, "header: flags"))
+ {
+ return false;
+ }
+
+ if (!read_uint32(buffer, &extensionLength, "header: extension length"))
+ {
+ return false;
+ }
+ if (buffer->size < extensionLength)
+ {
+ fprintf(stderr,
+ "Too large header extension length: %d: %d",
+ (int)extensionLength,
+ (int)(buffer->size));
+ return false;
+ }
+ buffer->data += extensionLength;
+ buffer->size -= extensionLength;
+
+ return true;
+}
+
+static bool
+parse_tuples(Buffer* buffer, Oid* types, bool* finished)
+{
+ while (buffer->size > 0)
+ {
+ uint16_t i;
+ uint16_t nFields;
+
+ if (!read_uint16(buffer, &nFields, "tuple: number of fields"))
+ {
+ return false;
+ }
+ if (nFields == (uint16_t)-1)
+ {
+ *finished = true;
+ return true;
+ }
+
+ for (i = 0; i < nFields; i++)
+ {
+ Oid type = types[i];
+ uint32_t size;
+ if (!read_uint32(buffer, &size, "tuple: field size"))
+ {
+ return false;
+ }
+ if (size == (uint32_t)-1)
+ {
+ /* NULL */
+ continue;
+ }
+
+ switch (type)
+ {
+ case INT4OID:
+ {
+ uint32_t value;
+ if (!read_uint32(buffer, &value,
"tuple: field: integer"))
+ {
+ return false;
+ }
+ /* printf("%d\n", (int32_t)value); */
+ break;
+ }
+ case TEXTOID:
+ {
+ /* printf("%.*s\n", (int)size,
buffer->data); */
+ buffer->data += size;
+ buffer->size -= size;
+ break;
+ }
+ default:
+ fprintf(stderr,
+ "tuple: field: %u: Unsupported
type: %u: %u: %d\n",
+ i,
+ type,
+ size,
+ (int)(buffer->size));
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+int
+main(int argc, char** argv)
+{
+ PGconn* connection;
+ PGresult* result;
+ Oid* types = NULL;
+ struct timeval before;
+ struct timeval after;
+ bool inTuples = false;
+
+ if (getenv("PGDATABASE"))
+ {
+ connection = PQconnectdb("");
+ }
+ else
+ {
+ connection = PQconnectdb("dbname=afs_benchmark");
+ }
+ if (PQstatus(connection) != CONNECTION_OK)
+ {
+ fprintf(stderr, "failed to connect: %s\n",
PQerrorMessage(connection));
+ PQfinish(connection);
+ return EXIT_FAILURE;
+ }
+
+ gettimeofday(&before, NULL);
+ result = PQprepare(connection, "", "SELECT * FROM data", 0, NULL);
+ if (PQresultStatus(result) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr,
+ "failed to prepare to infer schema: %s\n",
+ PQerrorMessage(connection));
+ PQclear(result);
+ PQfinish(connection);
+ return EXIT_FAILURE;
+ }
+ PQclear(result);
+ result = PQdescribePrepared(connection, "");
+ if (PQresultStatus(result) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr,
+ "failed to describe prepared statement to infer schema:
%s\n",
+ PQerrorMessage(connection));
+ PQclear(result);
+ PQfinish(connection);
+ return EXIT_FAILURE;
+ }
+ {
+ int i;
+ int nFields = PQnfields(result);
+
+ types = malloc(sizeof(Oid) * PQnfields(result));
+ for (i = 0; i < nFields; i++)
+ {
+ types[i] = PQftype(result, i);
+ }
+ }
+ PQclear(result);
+
+ result = PQexec(connection, "COPY data TO STDOUT (FORMAT binary)");
+ if (PQresultStatus(result) != PGRES_COPY_OUT)
+ {
+ fprintf(stderr, "failed to copy: %s\n",
PQerrorMessage(connection));
+ free(types);
+ PQclear(result);
+ PQfinish(connection);
+ return EXIT_FAILURE;
+ }
+
+ while (true)
+ {
+ char* data;
+ bool finished = false;
+ Buffer buffer;
+ int size = PQgetCopyData(connection, &data, 0);
+ if (size == -1)
+ {
+ break;
+ }
+ if (size == -2)
+ {
+ fprintf(stderr, "failed to read copy data: %s\n",
PQerrorMessage(connection));
+ free(types);
+ PQclear(result);
+ PQfinish(connection);
+ return EXIT_FAILURE;
+ }
+ buffer.data = data;
+ buffer.size = (size_t)size;
+ if (!inTuples)
+ {
+ if (!parse_header(&buffer))
+ {
+ free(types);
+ PQclear(result);
+ PQfinish(connection);
+ return EXIT_FAILURE;
+ }
+ inTuples = true;
+ }
+ if (!parse_tuples(&buffer, types, &finished))
+ {
+ free(types);
+ PQclear(result);
+ PQfinish(connection);
+ return EXIT_FAILURE;
+ }
+ free(data);
+ if (finished)
+ {
+ break;
+ }
+ }
+ gettimeofday(&after, NULL);
+ printf("%.3f\n",
+ (after.tv_sec + (after.tv_usec / 1000000.0)) -
+ (before.tv_sec + (before.tv_usec / 1000000.0)));
+ free(types);
+ PQclear(result);
+ PQfinish(connection);
+
+ return EXIT_SUCCESS;
+}
diff --git a/benchmark/integer/graph.rb b/benchmark/graph.rb
similarity index 64%
copy from benchmark/integer/graph.rb
copy to benchmark/graph.rb
index 47072b0..9d6f3cd 100755
--- a/benchmark/integer/graph.rb
+++ b/benchmark/graph.rb
@@ -21,11 +21,19 @@ require "csv"
require "charty"
Charty::Backends.use("pyplot")
-data = CSV.read(File.join(__dir__, "result.csv"),
- headers: true,
- converters: :all)
-plotter = Charty.bar_plot(data: data,
- x: "N records",
- y: "Elapsed time (sec)",
- color: "Approach")
-plotter.save("result.svg")
+
+benchmarks = [
+ "integer",
+ "string",
+]
+benchmarks.each do |benchmark|
+ base_dir = File.join(__dir__, benchmark)
+ data = CSV.read(File.join(base_dir, "result.csv"),
+ headers: true,
+ converters: :all)
+ plotter = Charty.bar_plot(data: data,
+ x: "N records",
+ y: "Elapsed time (sec)",
+ color: "Approach")
+ plotter.save(File.join(base_dir, "result.svg"))
+end
diff --git a/benchmark/integer/README.md b/benchmark/integer/README.md
index 86fe02d..3777f78 100644
--- a/benchmark/integer/README.md
+++ b/benchmark/integer/README.md
@@ -21,30 +21,7 @@
## How to run
-Install Apache Arrow Flight SQL PostgreSQL adapter.
-
-Run PostgreSQL with the following configuration:
-
-```text
-shared_preload_libraries = 'arrow_flight_sql'
-```
-
-Prepare database:
-
-```bash
-psql postgres -c '\i benchmark/integer/prepare-1M.sql'
-```
-
-It creates `afs_benchmark` database and `data` table in the database.
-It also inserts 10M records with random integers to the table.
-
-Run the following programs:
-
-- `select.rb`: It uses Apache Arrow Flight SQL
-- `select`: It uses PostgreSQL's C API
-- `select.sql`: You need to use `psql` to run this
-
-All of them just run `SELECT * FROM data`.
+See the [README.md in the parent directory](../README.md).
## Result
@@ -53,30 +30,30 @@ Here is a benchmark result on the following environment:
- OS: Debian GNU/Linux sid
- CPU: AMD Ryzen 9 3900X 12-Core Processor
- Memory: 64GiB
-- PostgreSQL: 16 (not released yet)
- 019f8624664dbf1e25e2bd721c7e99822812d109
-- Apache Arrow: 12.0.0-SNAPSHOT
- 237705bf17486cfc35ab7d1ddfe59dd60f042ab8
+- PostgreSQL: 17 (not released yet)
+ 5d8aa8bcedae7376bd97e79052d606db4e4f8dd4
+- Apache Arrow: 15.0.0-SNAPSHOT
+ e62ec62e40b04b0bfce76d58369845d3aa96a419
- Apache Arrow Flight SQL PostgreSQL adapter:
- 0.1.0 (not released yet)
- 120e7bbd3fd580c892c988499d488c7e8b34efe2
+ 0.2.0 (not released yet)
+ 14df9b5fe61eda2d71bdfbf67c61a227741f616c

100K records:
-| Apache Arrow Flight SQL | C | psql |
-| ----------------------- | ----- | ----- |
-| 0.014 | 0.012 | 0.011 |
+| Apache Arrow Flight SQL | `SELECT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 0.015 | 0.015 | 0.012 |
1M records:
-| Apache Arrow Flight SQL | C | psql |
-| ----------------------- | ----- | ----- |
-| 0.069 | 0.116 | 0.107 |
+| Apache Arrow Flight SQL | `SELECT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 0.111 | 0.148 | 0.114 |
10M records:
-| Apache Arrow Flight SQL | C | psql |
-| ----------------------- | ----- | ----- |
-| 0.653 | 1.154 | 1.128 |
+| Apache Arrow Flight SQL | `SELECT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 0.958 | 1.502 | 1.162 |
diff --git a/benchmark/integer/copy.c b/benchmark/integer/copy.c
deleted file mode 100644
index 9a1ca04..0000000
--- a/benchmark/integer/copy.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-
-#include <libpq-fe.h>
-
-int
-main(int argc, char** argv)
-{
- PGconn* connection = PQconnectdb("dbname=afs_benchmark");
- PGresult* result;
- struct timeval before;
- struct timeval after;
-
- if (PQstatus(connection) != CONNECTION_OK)
- {
- fprintf(stderr, "failed to connect: %s\n",
PQerrorMessage(connection));
- PQfinish(connection);
- return EXIT_FAILURE;
- }
-
- gettimeofday(&before, NULL);
- result = PQexec(connection, "COPY data TO STDOUT (FORMAT binary)");
- if (PQresultStatus(result) != PGRES_COPY_OUT)
- {
- fprintf(stderr, "failed to copy: %s\n",
PQerrorMessage(connection));
- PQclear(result);
- PQfinish(connection);
- return EXIT_FAILURE;
- }
-
- while (true)
- {
- char* buffer;
- int size = PQgetCopyData(connection, &buffer, 0);
- if (size == -1)
- {
- break;
- }
- if (size == -2)
- {
- fprintf(stderr, "failed to read copy data: %s\n",
PQerrorMessage(connection));
- PQclear(result);
- PQfinish(connection);
- return EXIT_FAILURE;
- }
- /* printf("%.*s\n", size, buffer); */
- free(buffer);
- }
- gettimeofday(&after, NULL);
- printf("%.3fsec\n",
- (after.tv_sec + (after.tv_usec / 1000000.0)) -
- (before.tv_sec + (before.tv_usec / 1000000.0)));
- PQclear(result);
-
- return EXIT_SUCCESS;
-}
diff --git a/benchmark/integer/prepare-100K.sql
b/benchmark/integer/prepare-100K.sql
deleted file mode 100644
index 9c7812c..0000000
--- a/benchmark/integer/prepare-100K.sql
+++ /dev/null
@@ -1,26 +0,0 @@
--- 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.
-
-DROP DATABASE IF EXISTS afs_benchmark;
-CREATE DATABASE afs_benchmark;
-\c afs_benchmark
-
-DROP TABLE IF EXISTS data;
-CREATE TABLE data (int32 integer);
-INSERT INTO data
- SELECT random() * 10000
- FROM generate_series(1, 100000);
diff --git a/benchmark/integer/prepare-10M.sql
b/benchmark/integer/prepare-10M.sql
deleted file mode 100644
index 456c74f..0000000
--- a/benchmark/integer/prepare-10M.sql
+++ /dev/null
@@ -1,26 +0,0 @@
--- 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.
-
-DROP DATABASE IF EXISTS afs_benchmark;
-CREATE DATABASE afs_benchmark;
-\c afs_benchmark
-
-DROP TABLE IF EXISTS data;
-CREATE TABLE data (int32 integer);
-INSERT INTO data
- SELECT random() * 10000
- FROM generate_series(1, 10000000);
diff --git a/benchmark/integer/prepare-1M.sql b/benchmark/integer/prepare-1M.sql
deleted file mode 100644
index 33d9ef8..0000000
--- a/benchmark/integer/prepare-1M.sql
+++ /dev/null
@@ -1,26 +0,0 @@
--- 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.
-
-DROP DATABASE IF EXISTS afs_benchmark;
-CREATE DATABASE afs_benchmark;
-\c afs_benchmark
-
-DROP TABLE IF EXISTS data;
-CREATE TABLE data (int32 integer);
-INSERT INTO data
- SELECT random() * 10000
- FROM generate_series(1, 1000000);
diff --git a/benchmark/integer/graph.rb b/benchmark/integer/prepare-sql.sh
similarity index 66%
copy from benchmark/integer/graph.rb
copy to benchmark/integer/prepare-sql.sh
index 47072b0..181992a 100755
--- a/benchmark/integer/graph.rb
+++ b/benchmark/integer/prepare-sql.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby
+#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -17,15 +17,25 @@
# specific language governing permissions and limitations
# under the License.
-require "csv"
-require "charty"
+set -eu
-Charty::Backends.use("pyplot")
-data = CSV.read(File.join(__dir__, "result.csv"),
- headers: true,
- converters: :all)
-plotter = Charty.bar_plot(data: data,
- x: "N records",
- y: "Elapsed time (sec)",
- color: "Approach")
-plotter.save("result.svg")
+size=100000
+db_name=afs_benchmark
+if [ $# -gt 0 ]; then
+ size="${1}"
+fi
+if [ $# -gt 1 ]; then
+ db_name="${2}"
+fi
+
+cat <<SQL
+DROP DATABASE IF EXISTS ${db_name};
+CREATE DATABASE ${db_name};
+\\c ${db_name}
+
+DROP TABLE IF EXISTS data;
+CREATE TABLE data (int32 integer);
+INSERT INTO data
+ SELECT random() * 10000
+ FROM generate_series(1, ${size});
+SQL
diff --git a/benchmark/integer/result.csv b/benchmark/integer/result.csv
index 26be7eb..bb27a19 100644
--- a/benchmark/integer/result.csv
+++ b/benchmark/integer/result.csv
@@ -1,10 +1,10 @@
Approach,N records,Elapsed time (sec)
-Apache Arrow Flight SQL,100000,0.014
-C,100000,0.012
-psql,100000,0.011
-Apache Arrow Flight SQL,1000000,0.069
-C,1000000,0.116
-psql,1000000,0.107
-Apache Arrow Flight SQL,10000000,0.653
-C,10000000,1.154
-psql,10000000,1.128
+Apache Arrow Flight SQL,100000,0.015
+SELECT,100000,0.015
+COPY,100000,0.012
+Apache Arrow Flight SQL,1000000,0.111
+SELECT,1000000,0.148
+COPY,1000000,0.114
+Apache Arrow Flight SQL,10000000,0.958
+SELECT,10000000,1.502
+COPY,10000000,1.162
diff --git a/benchmark/integer/result.svg b/benchmark/integer/result.svg
index 64c0bec..f8ed487 100644
--- a/benchmark/integer/result.svg
+++ b/benchmark/integer/result.svg
@@ -6,7 +6,7 @@
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<cc:Work>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
- <dc:date>2023-03-09T12:54:01.164041</dc:date>
+ <dc:date>2023-11-13T18:19:07.890284</dc:date>
<dc:format>image/svg+xml</dc:format>
<dc:creator>
<cc:Agent>
@@ -40,42 +40,42 @@ z
<g id="patch_3">
<path d="M 69.82144 307.584
L 100.93056 307.584
-L 100.93056 304.509338
-L 69.82144 304.509338
+L 100.93056 305.052975
+L 69.82144 305.052975
z
-" clip-path="url(#p3572019ee8)" style="fill: #1f77b4"/>
+" clip-path="url(#pe972ace1b8)" style="fill: #1f77b4"/>
</g>
<g id="patch_4">
<path d="M 188.86144 307.584
L 219.97056 307.584
-L 219.97056 292.430308
-L 188.86144 292.430308
+L 219.97056 288.854413
+L 188.86144 288.854413
z
-" clip-path="url(#p3572019ee8)" style="fill: #1f77b4"/>
+" clip-path="url(#pe972ace1b8)" style="fill: #1f77b4"/>
</g>
<g id="patch_5">
<path d="M 307.90144 307.584
L 339.01056 307.584
-L 339.01056 164.172977
-L 307.90144 164.172977
+L 339.01056 145.935851
+L 307.90144 145.935851
z
-" clip-path="url(#p3572019ee8)" style="fill: #1f77b4"/>
+" clip-path="url(#pe972ace1b8)" style="fill: #1f77b4"/>
</g>
<g id="patch_6">
<path d="M 101.56544 307.584
L 132.67456 307.584
-L 132.67456 304.948575
-L 101.56544 304.948575
+L 132.67456 305.052975
+L 101.56544 305.052975
z
-" clip-path="url(#p3572019ee8)" style="fill: #ff7f0e"/>
+" clip-path="url(#pe972ace1b8)" style="fill: #ff7f0e"/>
</g>
<g id="patch_7">
<path d="M 220.60544 307.584
L 251.71456 307.584
-L 251.71456 282.108229
-L 220.60544 282.108229
+L 251.71456 282.611217
+L 220.60544 282.611217
z
-" clip-path="url(#p3572019ee8)" style="fill: #ff7f0e"/>
+" clip-path="url(#pe972ace1b8)" style="fill: #ff7f0e"/>
</g>
<g id="patch_8">
<path d="M 339.64544 307.584
@@ -83,42 +83,42 @@ L 370.75456 307.584
L 370.75456 54.144
L 339.64544 54.144
z
-" clip-path="url(#p3572019ee8)" style="fill: #ff7f0e"/>
+" clip-path="url(#pe972ace1b8)" style="fill: #ff7f0e"/>
</g>
<g id="patch_9">
<path d="M 133.30944 307.584
L 164.41856 307.584
-L 164.41856 305.168194
-L 133.30944 305.168194
+L 164.41856 305.55918
+L 133.30944 305.55918
z
-" clip-path="url(#p3572019ee8)" style="fill: #2ca02c"/>
+" clip-path="url(#pe972ace1b8)" style="fill: #2ca02c"/>
</g>
<g id="patch_10">
<path d="M 252.34944 307.584
L 283.45856 307.584
-L 283.45856 284.084797
-L 252.34944 284.084797
+L 283.45856 288.348208
+L 252.34944 288.348208
z
-" clip-path="url(#p3572019ee8)" style="fill: #2ca02c"/>
+" clip-path="url(#pe972ace1b8)" style="fill: #2ca02c"/>
</g>
<g id="patch_11">
<path d="M 371.38944 307.584
L 402.49856 307.584
-L 402.49856 59.854087
-L 371.38944 59.854087
+L 402.49856 111.513907
+L 371.38944 111.513907
z
-" clip-path="url(#p3572019ee8)" style="fill: #2ca02c"/>
+" clip-path="url(#pe972ace1b8)" style="fill: #2ca02c"/>
</g>
<g id="matplotlib.axis_1">
<g id="xtick_1">
<g id="line2d_1">
<defs>
- <path id="m42c665c27f" d="M 0 0
+ <path id="mdc567500bd" d="M 0 0
L 0 3.5
" style="stroke: #000000; stroke-width: 0.8"/>
</defs>
<g>
- <use xlink:href="#m42c665c27f" x="117.12" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#mdc567500bd" x="117.12" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_1">
@@ -173,7 +173,7 @@ z
<g id="xtick_2">
<g id="line2d_2">
<g>
- <use xlink:href="#m42c665c27f" x="236.16" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#mdc567500bd" x="236.16" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_2">
@@ -192,7 +192,7 @@ z
<g id="xtick_3">
<g id="line2d_3">
<g>
- <use xlink:href="#m42c665c27f" x="355.2" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#mdc567500bd" x="355.2" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_3">
@@ -385,12 +385,12 @@ z
<g id="ytick_1">
<g id="line2d_4">
<defs>
- <path id="meee343289d" d="M 0 0
+ <path id="m3c2589d813" d="M 0 0
L -3.5 0
" style="stroke: #000000; stroke-width: 0.8"/>
</defs>
<g>
- <use xlink:href="#meee343289d" x="57.6" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m3c2589d813" x="57.6" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_5">
@@ -414,12 +414,12 @@ z
<g id="ytick_2">
<g id="line2d_5">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="263.660256" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m3c2589d813" x="57.6" y="273.836996" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_6">
<!-- 0.2 -->
- <g transform="translate(34.696875 267.459475) scale(0.1 -0.1)">
+ <g transform="translate(34.696875 277.636215) scale(0.1 -0.1)">
<defs>
<path id="DejaVuSans-32" d="M 1228 531
L 3431 531
@@ -455,12 +455,12 @@ z
<g id="ytick_3">
<g id="line2d_6">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="219.736513" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m3c2589d813" x="57.6" y="240.089992" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_7">
<!-- 0.4 -->
- <g transform="translate(34.696875 223.535732) scale(0.1 -0.1)">
+ <g transform="translate(34.696875 243.889211) scale(0.1 -0.1)">
<defs>
<path id="DejaVuSans-34" d="M 2419 4116
L 825 1625
@@ -491,12 +491,12 @@ z
<g id="ytick_4">
<g id="line2d_7">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="175.812769" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m3c2589d813" x="57.6" y="206.342988" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_8">
<!-- 0.6 -->
- <g transform="translate(34.696875 179.611988) scale(0.1 -0.1)">
+ <g transform="translate(34.696875 210.142207) scale(0.1 -0.1)">
<defs>
<path id="DejaVuSans-36" d="M 2113 2584
Q 1688 2584 1439 2293
@@ -538,12 +538,12 @@ z
<g id="ytick_5">
<g id="line2d_8">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="131.889026" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m3c2589d813" x="57.6" y="172.595984" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_9">
<!-- 0.8 -->
- <g transform="translate(34.696875 135.688245) scale(0.1 -0.1)">
+ <g transform="translate(34.696875 176.395203) scale(0.1 -0.1)">
<defs>
<path id="DejaVuSans-38" d="M 2034 2216
Q 1584 2216 1326 1975
@@ -594,12 +594,12 @@ z
<g id="ytick_6">
<g id="line2d_9">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="87.965282" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m3c2589d813" x="57.6" y="138.84898" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_10">
<!-- 1.0 -->
- <g transform="translate(34.696875 91.764501) scale(0.1 -0.1)">
+ <g transform="translate(34.696875 142.648199) scale(0.1 -0.1)">
<use xlink:href="#DejaVuSans-31"/>
<use xlink:href="#DejaVuSans-2e" x="63.623047"/>
<use xlink:href="#DejaVuSans-30" x="95.410156"/>
@@ -609,19 +609,34 @@ z
<g id="ytick_7">
<g id="line2d_10">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="44.041539" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m3c2589d813" x="57.6" y="105.101976" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_11">
<!-- 1.2 -->
- <g transform="translate(34.696875 47.840758) scale(0.1 -0.1)">
+ <g transform="translate(34.696875 108.901195) scale(0.1 -0.1)">
<use xlink:href="#DejaVuSans-31"/>
<use xlink:href="#DejaVuSans-2e" x="63.623047"/>
<use xlink:href="#DejaVuSans-32" x="95.410156"/>
</g>
</g>
</g>
- <g id="text_12">
+ <g id="ytick_8">
+ <g id="line2d_11">
+ <g>
+ <use xlink:href="#m3c2589d813" x="57.6" y="71.354972" style="stroke:
#000000; stroke-width: 0.8"/>
+ </g>
+ </g>
+ <g id="text_12">
+ <!-- 1.4 -->
+ <g transform="translate(34.696875 75.154191) scale(0.1 -0.1)">
+ <use xlink:href="#DejaVuSans-31"/>
+ <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
+ <use xlink:href="#DejaVuSans-34" x="95.410156"/>
+ </g>
+ </g>
+ </g>
+ <g id="text_13">
<!-- Elapsed time (sec) -->
<g transform="translate(28.617187 220.976438) rotate(-90) scale(0.1
-0.1)">
<defs>
@@ -818,32 +833,32 @@ z
</g>
</g>
</g>
- <g id="line2d_11">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
- </g>
<g id="line2d_12">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_13">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_14">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_15">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_16">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_17">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_18">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_19">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ </g>
+ <g id="line2d_20">
+ <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="patch_12">
<path d="M 57.6 307.584
@@ -879,7 +894,7 @@ Q 62.6 108.1845 64.6 108.1845
z
" style="fill: #ffffff; opacity: 0.8; stroke: #cccccc; stroke-linejoin:
miter"/>
</g>
- <g id="text_13">
+ <g id="text_14">
<!-- Approach -->
<g transform="translate(118.6 58.070438) scale(0.1 -0.1)">
<defs>
@@ -937,7 +952,7 @@ L 66.6 65.748563
z
" style="fill: #1f77b4"/>
</g>
- <g id="text_14">
+ <g id="text_15">
<!-- Apache Arrow Flight SQL -->
<g transform="translate(94.6 72.748563) scale(0.1 -0.1)">
<defs>
@@ -1104,8 +1119,8 @@ L 66.6 80.426688
z
" style="fill: #ff7f0e"/>
</g>
- <g id="text_15">
- <!-- C -->
+ <g id="text_16">
+ <!-- SELECT -->
<g transform="translate(94.6 87.426688) scale(0.1 -0.1)">
<defs>
<path id="DejaVuSans-43" d="M 4122 4306
@@ -1128,9 +1143,25 @@ Q 1578 4750 2638 4750
Q 3056 4750 3426 4639
Q 3797 4528 4122 4306
z
+" transform="scale(0.015625)"/>
+ <path id="DejaVuSans-54" d="M -19 4666
+L 3928 4666
+L 3928 4134
+L 2272 4134
+L 2272 0
+L 1638 0
+L 1638 4134
+L -19 4134
+L -19 4666
+z
" transform="scale(0.015625)"/>
</defs>
- <use xlink:href="#DejaVuSans-43"/>
+ <use xlink:href="#DejaVuSans-53"/>
+ <use xlink:href="#DejaVuSans-45" x="63.476562"/>
+ <use xlink:href="#DejaVuSans-4c" x="126.660156"/>
+ <use xlink:href="#DejaVuSans-45" x="182.373047"/>
+ <use xlink:href="#DejaVuSans-43" x="245.556641"/>
+ <use xlink:href="#DejaVuSans-54" x="315.380859"/>
</g>
</g>
<g id="patch_19">
@@ -1141,48 +1172,76 @@ L 66.6 95.104813
z
" style="fill: #2ca02c"/>
</g>
- <g id="text_16">
- <!-- psql -->
+ <g id="text_17">
+ <!-- COPY -->
<g transform="translate(94.6 102.104813) scale(0.1 -0.1)">
<defs>
- <path id="DejaVuSans-71" d="M 947 1747
-Q 947 1113 1208 752
-Q 1469 391 1925 391
-Q 2381 391 2643 752
-Q 2906 1113 2906 1747
-Q 2906 2381 2643 2742
-Q 2381 3103 1925 3103
-Q 1469 3103 1208 2742
-Q 947 2381 947 1747
+ <path id="DejaVuSans-4f" d="M 2522 4238
+Q 1834 4238 1429 3725
+Q 1025 3213 1025 2328
+Q 1025 1447 1429 934
+Q 1834 422 2522 422
+Q 3209 422 3611 934
+Q 4013 1447 4013 2328
+Q 4013 3213 3611 3725
+Q 3209 4238 2522 4238
z
-M 2906 525
-Q 2725 213 2448 61
-Q 2172 -91 1784 -91
-Q 1150 -91 751 415
-Q 353 922 353 1747
-Q 353 2572 751 3078
-Q 1150 3584 1784 3584
-Q 2172 3584 2448 3432
-Q 2725 3281 2906 2969
-L 2906 3500
-L 3481 3500
-L 3481 -1331
-L 2906 -1331
-L 2906 525
+M 2522 4750
+Q 3503 4750 4090 4092
+Q 4678 3434 4678 2328
+Q 4678 1225 4090 567
+Q 3503 -91 2522 -91
+Q 1538 -91 948 565
+Q 359 1222 359 2328
+Q 359 3434 948 4092
+Q 1538 4750 2522 4750
+z
+" transform="scale(0.015625)"/>
+ <path id="DejaVuSans-50" d="M 1259 4147
+L 1259 2394
+L 2053 2394
+Q 2494 2394 2734 2622
+Q 2975 2850 2975 3272
+Q 2975 3691 2734 3919
+Q 2494 4147 2053 4147
+L 1259 4147
+z
+M 628 4666
+L 2053 4666
+Q 2838 4666 3239 4311
+Q 3641 3956 3641 3272
+Q 3641 2581 3239 2228
+Q 2838 1875 2053 1875
+L 1259 1875
+L 1259 0
+L 628 0
+L 628 4666
+z
+" transform="scale(0.015625)"/>
+ <path id="DejaVuSans-59" d="M -13 4666
+L 666 4666
+L 1959 2747
+L 3244 4666
+L 3922 4666
+L 2272 2222
+L 2272 0
+L 1638 0
+L 1638 2222
+L -13 4666
z
" transform="scale(0.015625)"/>
</defs>
- <use xlink:href="#DejaVuSans-70"/>
- <use xlink:href="#DejaVuSans-73" x="63.476562"/>
- <use xlink:href="#DejaVuSans-71" x="115.576172"/>
- <use xlink:href="#DejaVuSans-6c" x="179.052734"/>
+ <use xlink:href="#DejaVuSans-43"/>
+ <use xlink:href="#DejaVuSans-4f" x="69.824219"/>
+ <use xlink:href="#DejaVuSans-50" x="148.535156"/>
+ <use xlink:href="#DejaVuSans-59" x="206.587891"/>
</g>
</g>
</g>
</g>
</g>
<defs>
- <clipPath id="p3572019ee8">
+ <clipPath id="pe972ace1b8">
<rect x="57.6" y="41.472" width="357.12" height="266.112"/>
</clipPath>
</defs>
diff --git a/benchmark/markdown.rb b/benchmark/markdown.rb
new file mode 100755
index 0000000..e4225e4
--- /dev/null
+++ b/benchmark/markdown.rb
@@ -0,0 +1,77 @@
+#!/usr/bin/env ruby
+#
+# 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.
+
+require "csv"
+
+benchmarks = [
+ "integer",
+ "string",
+]
+
+def format_n_records(n_records)
+ if n_records < 1_000_000
+ "%dK" % (n_records / 1_000.0)
+ else n_records
+ "%dM" % (n_records / 1_000_000.0)
+ end
+end
+
+benchmarks.each do |benchmark|
+ base_dir = File.join(__dir__, benchmark)
+ data = CSV.read(File.join(base_dir, "result.csv"),
+ headers: true,
+ converters: :all)
+ readme_path = File.join(base_dir, "README.md")
+ graph_markdown = ""
+ readme = File.read(readme_path)
+ readme_before_graph_markdown =
+ readme.split(/^#{Regexp.escape(graph_markdown)}$/, 2)[0]
+ records_per_n = data.each.group_by do |row|
+ row["N records"]
+ end
+ result = ""
+ records_per_n.each do |n_records, rows|
+ result << "\n"
+ result << "#{format_n_records(n_records)} records:\n"
+ result << "\n"
+ approaches = rows.collect do |row|
+ approach = row["Approach"]
+ if approach == "Apache Arrow Flight SQL"
+ approach
+ else
+ "`#{approach}`"
+ end
+ end
+ result << ("| " + approaches.join(" | ") + " |\n")
+ separators = approaches.collect {|approach| "-" * approach.size}
+ result << ("| " + separators.join(" | ") + " |\n")
+ formatted_elapsed = approaches.zip(rows).collect do |approach, row|
+ width = approach.size
+ ("%.3f" % row["Elapsed time (sec)"]).ljust(width)
+ end
+ result << ("| " + formatted_elapsed.join(" | ") + " |\n")
+ end
+ File.write(readme_path, <<-README)
+#{readme_before_graph_markdown.strip}
+
+#{graph_markdown}
+
+#{result.strip}
+ README
+end
diff --git a/benchmark/integer/meson.build b/benchmark/meson.build
similarity index 86%
rename from benchmark/integer/meson.build
rename to benchmark/meson.build
index 4bfdea4..dfb06a0 100644
--- a/benchmark/integer/meson.build
+++ b/benchmark/meson.build
@@ -16,5 +16,5 @@
# under the License.
libpq = dependency('libpq')
-executable('copy', 'copy.c', dependencies: [libpq])
-executable('select', 'select.c', dependencies: [libpq])
+executable('copy', 'copy.c', dependencies: [libpq, postgresql])
+executable('select', 'select.c', dependencies: [libpq, postgresql])
diff --git a/benchmark/run.sh b/benchmark/run.sh
new file mode 100755
index 0000000..eaf8baa
--- /dev/null
+++ b/benchmark/run.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+#
+# 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.
+
+set -eu
+set -o pipefail
+
+base_dir=$(dirname "$0")
+
+measure()
+{
+ local n_tries=3
+ for i in $(seq ${n_tries}); do
+ "$@"
+ done | sort --numeric-sort | head -n 1
+}
+
+benchmarks=()
+benchmarks+=(integer)
+benchmarks+=(string)
+
+for benchmark in "${benchmarks[@]}"; do
+ result="${base_dir}/${benchmark}/result.csv"
+ echo "Approach,N records,Elapsed time (sec)" | tee "${result}"
+ sizes=()
+ sizes+=(100000)
+ sizes+=(1000000)
+ sizes+=(10000000)
+ for size in "${sizes[@]}"; do
+ export PGDATABASE="afs_benchmark_${benchmark}_${size}"
+ echo "${benchmark}: ${size}: preparing"
+ "${base_dir}/${benchmark}/prepare-sql.sh" "${size}" "${PGDATABASE}" | \
+ psql -d postgres
+
+ echo "${benchmark}: ${size}: Apache Arrow Flight SQL"
+ elapsed_time=$(measure "${base_dir}/select.rb")
+ echo "Apache Arrow Flight SQL,${size},${elapsed_time}" | tee -a "${result}"
+
+ echo "${benchmark}: ${size}: SELECT"
+ elapsed_time=$(measure benchmark/select)
+ echo "SELECT,${size},${elapsed_time}" | tee -a "${result}"
+
+ echo "${benchmark}: ${size}: COPY"
+ elapsed_time=$(measure benchmark/copy)
+ echo "COPY,${size},${elapsed_time}" | tee -a "${result}"
+ done
+done
diff --git a/benchmark/integer/select-adbc-flight-sql.rb
b/benchmark/select-adbc-flight-sql.rb
similarity index 100%
rename from benchmark/integer/select-adbc-flight-sql.rb
rename to benchmark/select-adbc-flight-sql.rb
diff --git a/benchmark/integer/select-adbc-postgresql.rb
b/benchmark/select-adbc-postgresql.rb
similarity index 100%
copy from benchmark/integer/select-adbc-postgresql.rb
copy to benchmark/select-adbc-postgresql.rb
diff --git a/dev/release/rat_exclude_files.txt b/benchmark/select-pandas.py
old mode 100644
new mode 100755
similarity index 68%
copy from dev/release/rat_exclude_files.txt
copy to benchmark/select-pandas.py
index 5d1761d..4facea4
--- a/dev/release/rat_exclude_files.txt
+++ b/benchmark/select-pandas.py
@@ -1,3 +1,5 @@
+#!/usr/bin/env python3
+#
# 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
@@ -15,10 +17,14 @@
# specific language governing permissions and limitations
# under the License.
-benchmark/integer/result.csv
-benchmark/integer/result.svg
-compile_commands.json
-dev/release/apache-rat-*.jar
-dev/release/filtered_rat.txt
-dev/release/rat.xml
-doc/source/_static/switcher.json
+import time
+
+import pandas
+import sqlalchemy
+
+database = os.environ.get("PGDATABASE", "afs_benchmark")
+engine = sqlalchemy.create_engine("postgresql:///{database}")
+with engine.connect() as connection, connection.begin():
+ start = time.perf_counter()
+ pandas.read_sql_table("data", connection)
+ print(time.perf_counter() - start)
diff --git a/benchmark/integer/select-adbc-postgresql.rb
b/benchmark/select-polars.py
similarity index 60%
rename from benchmark/integer/select-adbc-postgresql.rb
rename to benchmark/select-polars.py
index f78f1c8..652674a 100755
--- a/benchmark/integer/select-adbc-postgresql.rb
+++ b/benchmark/select-polars.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby
+#!/usr/bin/env python3
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -17,21 +17,19 @@
# specific language governing permissions and limitations
# under the License.
-require "time"
+import os
+import time
-require "adbc"
+import polars
+
+user = os.environ.get("PGUSER", os.environ["USER"])
+password = os.environ.get("PGPASSWORD", "")
+host = os.environ.get("PGHOST", "localhost")
+port = os.environ.get("PGPORT", "5432")
+database = os.environ.get("PGDATABASE", "afs_benchmark")
+uri = f"postgres://{user}:{password}@{host}:{port}/{database}"
+start = time.perf_counter()
+polars.read_database_uri(query="SELECT * FROM data",
+ uri=uri)
+print(time.perf_counter() - start)
-options = {
- driver: "adbc_driver_postgresql",
- uri: "postgresql://127.0.0.1:5432/afs_benchmark",
-}
-ADBC::Database.open(**options) do |database|
- database.connect do |connection|
- connection.open_statement do |statement|
- before = Time.now
- _table, _n_rows_affected = statement.query("SELECT * FROM data")
- # p _table
- puts("%.3fsec" % (Time.now - before))
- end
- end
-end
diff --git a/benchmark/integer/select.c b/benchmark/select.c
similarity index 62%
rename from benchmark/integer/select.c
rename to benchmark/select.c
index bf3ad9d..7711bee 100644
--- a/benchmark/integer/select.c
+++ b/benchmark/select.c
@@ -17,16 +17,54 @@
* under the License.
*/
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <libpq-fe.h>
+#include <catalog/pg_type_d.h>
+
+#define UNUSED(x) ((void)(x))
+
+static bool
+parse_value(PGresult* result, int iTuple, int iField)
+{
+ Oid type = PQftype(result, iField);
+ char* value = PQgetvalue(result, iTuple, iField);
+ int length = PQgetlength(result, iTuple, iField);
+ switch (type)
+ {
+ case INT4OID:
+ {
+ char* end;
+ long integer = strtol(value, &end, 10);
+ if (end != value + length)
+ {
+ fprintf(stderr, "failed to parse integer value:
<%s>\n", value);
+ return false;
+ }
+ UNUSED(integer);
+ /* printf("%ld\n", integer); */
+ }
+ break;
+ case TEXTOID:
+ {
+ /* printf("%s\n", value); */
+ }
+ break;
+ default:
+ fprintf(stderr, "Unsupported type: %u\n", type);
+ return false;
+ }
+ return true;
+}
+
int
main(int argc, char** argv)
{
- PGconn* connection = PQconnectdb("dbname=afs_benchmark");
+ PGconn* connection;
PGresult* result;
struct timeval before;
struct timeval after;
@@ -35,6 +73,14 @@ main(int argc, char** argv)
int nTuples;
int iTuple;
+ if (getenv("PGDATABASE"))
+ {
+ connection = PQconnectdb("");
+ }
+ else
+ {
+ connection = PQconnectdb("dbname=afs_benchmark");
+ }
if (PQstatus(connection) != CONNECTION_OK)
{
fprintf(stderr, "failed to connect: %s\n",
PQerrorMessage(connection));
@@ -58,14 +104,24 @@ main(int argc, char** argv)
{
for (iField = 0; iField < nFields; iField++)
{
- PQgetvalue(result, iTuple, iField);
+ if (PQgetisnull(result, iTuple, iField))
+ {
+ continue;
+ }
+ if (!parse_value(result, iTuple, iField))
+ {
+ PQclear(result);
+ PQfinish(connection);
+ return EXIT_FAILURE;
+ }
}
}
gettimeofday(&after, NULL);
- printf("%.3fsec\n",
+ printf("%.3f\n",
(after.tv_sec + (after.tv_usec / 1000000.0)) -
(before.tv_sec + (before.tv_usec / 1000000.0)));
PQclear(result);
+ PQfinish(connection);
return EXIT_SUCCESS;
}
diff --git a/benchmark/integer/select.rb b/benchmark/select.rb
similarity index 90%
rename from benchmark/integer/select.rb
rename to benchmark/select.rb
index f676e42..07f3550 100755
--- a/benchmark/integer/select.rb
+++ b/benchmark/select.rb
@@ -22,7 +22,8 @@ require "time"
require "arrow-flight-sql"
call_options = ArrowFlight::CallOptions.new
-call_options.add_header("x-flight-sql-database", "afs_benchmark")
+call_options.add_header("x-flight-sql-database",
+ ENV["PGDATABASE"] || "afs_benchmark")
client = ArrowFlight::Client.new("grpc://127.0.0.1:15432")
client.authenticate_basic(ENV["PGUSER"] || ENV["USER"],
ENV["PGPASSWORD"] || "",
@@ -35,4 +36,4 @@ endpoint = info.endpoints.first
reader = sql_client.do_get(endpoint.ticket, call_options)
_table = reader.read_all
# p _table
-puts("%.3fsec" % (Time.now - before))
+puts("%.3f" % (Time.now - before))
diff --git a/benchmark/integer/select.sql b/benchmark/select.sql
similarity index 100%
rename from benchmark/integer/select.sql
rename to benchmark/select.sql
diff --git a/benchmark/string/README.md b/benchmark/string/README.md
new file mode 100644
index 0000000..473f7c4
--- /dev/null
+++ b/benchmark/string/README.md
@@ -0,0 +1,59 @@
+<!--
+ 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.
+-->
+
+# Benchmark - only with string data
+
+## How to run
+
+See the [`README.md` in the parent directory](../README.md).
+
+## Result
+
+Here is a benchmark result on the following environment:
+
+- OS: Debian GNU/Linux sid
+- CPU: AMD Ryzen 9 3900X 12-Core Processor
+- Memory: 64GiB
+- PostgreSQL: 17 (not released yet)
+ 5d8aa8bcedae7376bd97e79052d606db4e4f8dd4
+- Apache Arrow: 15.0.0-SNAPSHOT
+ e62ec62e40b04b0bfce76d58369845d3aa96a419
+- Apache Arrow Flight SQL PostgreSQL adapter:
+ 0.2.0 (not released yet)
+ 14df9b5fe61eda2d71bdfbf67c61a227741f616c
+
+
+
+100K records:
+
+| Apache Arrow Flight SQL | `SELECT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 0.047 | 0.017 | 0.017 |
+
+1M records:
+
+| Apache Arrow Flight SQL | `SELECT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 0.512 | 0.155 | 0.153 |
+
+10M records:
+
+| Apache Arrow Flight SQL | `SELECT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 2.951 | 1.706 | 1.640 |
diff --git a/benchmark/integer/graph.rb b/benchmark/string/prepare-sql.sh
similarity index 65%
rename from benchmark/integer/graph.rb
rename to benchmark/string/prepare-sql.sh
index 47072b0..6a55a51 100755
--- a/benchmark/integer/graph.rb
+++ b/benchmark/string/prepare-sql.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby
+#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -17,15 +17,27 @@
# specific language governing permissions and limitations
# under the License.
-require "csv"
-require "charty"
+set -eu
-Charty::Backends.use("pyplot")
-data = CSV.read(File.join(__dir__, "result.csv"),
- headers: true,
- converters: :all)
-plotter = Charty.bar_plot(data: data,
- x: "N records",
- y: "Elapsed time (sec)",
- color: "Approach")
-plotter.save("result.svg")
+size=100000
+db_name=afs_benchmark
+if [ $# -gt 0 ]; then
+ size="${1}"
+fi
+if [ $# -gt 1 ]; then
+ db_name="${2}"
+fi
+
+cat <<SQL
+DROP DATABASE IF EXISTS ${db_name};
+CREATE DATABASE ${db_name};
+\\c ${db_name}
+
+DROP TABLE IF EXISTS data;
+CREATE TABLE data (
+ string text
+);
+INSERT INTO data
+ SELECT md5(clock_timestamp()::text) || md5(clock_timestamp()::text)
+ FROM generate_series(1, ${size});
+SQL
diff --git a/benchmark/string/result.csv b/benchmark/string/result.csv
new file mode 100644
index 0000000..3a5a181
--- /dev/null
+++ b/benchmark/string/result.csv
@@ -0,0 +1,10 @@
+Approach,N records,Elapsed time (sec)
+Apache Arrow Flight SQL,100000,0.047
+SELECT,100000,0.017
+COPY,100000,0.017
+Apache Arrow Flight SQL,1000000,0.512
+SELECT,1000000,0.155
+COPY,1000000,0.153
+Apache Arrow Flight SQL,10000000,2.951
+SELECT,10000000,1.706
+COPY,10000000,1.640
diff --git a/benchmark/integer/result.svg b/benchmark/string/result.svg
similarity index 80%
copy from benchmark/integer/result.svg
copy to benchmark/string/result.svg
index 64c0bec..590670f 100644
--- a/benchmark/integer/result.svg
+++ b/benchmark/string/result.svg
@@ -6,7 +6,7 @@
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<cc:Work>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
- <dc:date>2023-03-09T12:54:01.164041</dc:date>
+ <dc:date>2023-11-13T18:19:08.495288</dc:date>
<dc:format>image/svg+xml</dc:format>
<dc:creator>
<cc:Agent>
@@ -40,85 +40,85 @@ z
<g id="patch_3">
<path d="M 69.82144 307.584
L 100.93056 307.584
-L 100.93056 304.509338
-L 69.82144 304.509338
+L 100.93056 303.547511
+L 69.82144 303.547511
z
-" clip-path="url(#p3572019ee8)" style="fill: #1f77b4"/>
+" clip-path="url(#p3aca9fb4c4)" style="fill: #1f77b4"/>
</g>
<g id="patch_4">
<path d="M 188.86144 307.584
L 219.97056 307.584
-L 219.97056 292.430308
-L 188.86144 292.430308
+L 219.97056 263.612031
+L 188.86144 263.612031
z
-" clip-path="url(#p3572019ee8)" style="fill: #1f77b4"/>
+" clip-path="url(#p3aca9fb4c4)" style="fill: #1f77b4"/>
</g>
<g id="patch_5">
<path d="M 307.90144 307.584
L 339.01056 307.584
-L 339.01056 164.172977
-L 307.90144 164.172977
+L 339.01056 54.144
+L 307.90144 54.144
z
-" clip-path="url(#p3572019ee8)" style="fill: #1f77b4"/>
+" clip-path="url(#p3aca9fb4c4)" style="fill: #1f77b4"/>
</g>
<g id="patch_6">
<path d="M 101.56544 307.584
L 132.67456 307.584
-L 132.67456 304.948575
-L 101.56544 304.948575
+L 132.67456 306.123993
+L 101.56544 306.123993
z
-" clip-path="url(#p3572019ee8)" style="fill: #ff7f0e"/>
+" clip-path="url(#p3aca9fb4c4)" style="fill: #ff7f0e"/>
</g>
<g id="patch_7">
<path d="M 220.60544 307.584
L 251.71456 307.584
-L 251.71456 282.108229
-L 220.60544 282.108229
+L 251.71456 294.272174
+L 220.60544 294.272174
z
-" clip-path="url(#p3572019ee8)" style="fill: #ff7f0e"/>
+" clip-path="url(#p3aca9fb4c4)" style="fill: #ff7f0e"/>
</g>
<g id="patch_8">
<path d="M 339.64544 307.584
L 370.75456 307.584
-L 370.75456 54.144
-L 339.64544 54.144
+L 370.75456 161.068026
+L 339.64544 161.068026
z
-" clip-path="url(#p3572019ee8)" style="fill: #ff7f0e"/>
+" clip-path="url(#p3aca9fb4c4)" style="fill: #ff7f0e"/>
</g>
<g id="patch_9">
<path d="M 133.30944 307.584
L 164.41856 307.584
-L 164.41856 305.168194
-L 133.30944 305.168194
+L 164.41856 306.123993
+L 133.30944 306.123993
z
-" clip-path="url(#p3572019ee8)" style="fill: #2ca02c"/>
+" clip-path="url(#p3aca9fb4c4)" style="fill: #2ca02c"/>
</g>
<g id="patch_10">
<path d="M 252.34944 307.584
L 283.45856 307.584
-L 283.45856 284.084797
-L 252.34944 284.084797
+L 283.45856 294.443939
+L 252.34944 294.443939
z
-" clip-path="url(#p3572019ee8)" style="fill: #2ca02c"/>
+" clip-path="url(#p3aca9fb4c4)" style="fill: #2ca02c"/>
</g>
<g id="patch_11">
<path d="M 371.38944 307.584
L 402.49856 307.584
-L 402.49856 59.854087
-L 371.38944 59.854087
+L 402.49856 166.736287
+L 371.38944 166.736287
z
-" clip-path="url(#p3572019ee8)" style="fill: #2ca02c"/>
+" clip-path="url(#p3aca9fb4c4)" style="fill: #2ca02c"/>
</g>
<g id="matplotlib.axis_1">
<g id="xtick_1">
<g id="line2d_1">
<defs>
- <path id="m42c665c27f" d="M 0 0
+ <path id="mc298820655" d="M 0 0
L 0 3.5
" style="stroke: #000000; stroke-width: 0.8"/>
</defs>
<g>
- <use xlink:href="#m42c665c27f" x="117.12" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#mc298820655" x="117.12" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_1">
@@ -173,7 +173,7 @@ z
<g id="xtick_2">
<g id="line2d_2">
<g>
- <use xlink:href="#m42c665c27f" x="236.16" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#mc298820655" x="236.16" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_2">
@@ -192,7 +192,7 @@ z
<g id="xtick_3">
<g id="line2d_3">
<g>
- <use xlink:href="#m42c665c27f" x="355.2" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#mc298820655" x="355.2" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_3">
@@ -385,12 +385,12 @@ z
<g id="ytick_1">
<g id="line2d_4">
<defs>
- <path id="meee343289d" d="M 0 0
+ <path id="m8afccf3ad6" d="M 0 0
L -3.5 0
" style="stroke: #000000; stroke-width: 0.8"/>
</defs>
<g>
- <use xlink:href="#meee343289d" x="57.6" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m8afccf3ad6" x="57.6" y="307.584" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_5">
@@ -414,210 +414,177 @@ z
<g id="ytick_2">
<g id="line2d_5">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="263.660256" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m8afccf3ad6" x="57.6" y="264.642624" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_6">
- <!-- 0.2 -->
- <g transform="translate(34.696875 267.459475) scale(0.1 -0.1)">
+ <!-- 0.5 -->
+ <g transform="translate(34.696875 268.441843) scale(0.1 -0.1)">
<defs>
- <path id="DejaVuSans-32" d="M 1228 531
-L 3431 531
-L 3431 0
-L 469 0
-L 469 531
-Q 828 903 1448 1529
-Q 2069 2156 2228 2338
-Q 2531 2678 2651 2914
-Q 2772 3150 2772 3378
-Q 2772 3750 2511 3984
-Q 2250 4219 1831 4219
-Q 1534 4219 1204 4116
-Q 875 4013 500 3803
-L 500 4441
-Q 881 4594 1212 4672
-Q 1544 4750 1819 4750
-Q 2544 4750 2975 4387
-Q 3406 4025 3406 3419
-Q 3406 3131 3298 2873
-Q 3191 2616 2906 2266
-Q 2828 2175 2409 1742
-Q 1991 1309 1228 531
+ <path id="DejaVuSans-35" d="M 691 4666
+L 3169 4666
+L 3169 4134
+L 1269 4134
+L 1269 2991
+Q 1406 3038 1543 3061
+Q 1681 3084 1819 3084
+Q 2600 3084 3056 2656
+Q 3513 2228 3513 1497
+Q 3513 744 3044 326
+Q 2575 -91 1722 -91
+Q 1428 -91 1123 -41
+Q 819 9 494 109
+L 494 744
+Q 775 591 1075 516
+Q 1375 441 1709 441
+Q 2250 441 2565 725
+Q 2881 1009 2881 1497
+Q 2881 1984 2565 2268
+Q 2250 2553 1709 2553
+Q 1456 2553 1204 2497
+Q 953 2441 691 2322
+L 691 4666
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-30"/>
<use xlink:href="#DejaVuSans-2e" x="63.623047"/>
- <use xlink:href="#DejaVuSans-32" x="95.410156"/>
+ <use xlink:href="#DejaVuSans-35" x="95.410156"/>
</g>
</g>
</g>
<g id="ytick_3">
<g id="line2d_6">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="219.736513" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m8afccf3ad6" x="57.6" y="221.701248" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_7">
- <!-- 0.4 -->
- <g transform="translate(34.696875 223.535732) scale(0.1 -0.1)">
- <defs>
- <path id="DejaVuSans-34" d="M 2419 4116
-L 825 1625
-L 2419 1625
-L 2419 4116
-z
-M 2253 4666
-L 3047 4666
-L 3047 1625
-L 3713 1625
-L 3713 1100
-L 3047 1100
-L 3047 0
-L 2419 0
-L 2419 1100
-L 313 1100
-L 313 1709
-L 2253 4666
-z
-" transform="scale(0.015625)"/>
- </defs>
- <use xlink:href="#DejaVuSans-30"/>
+ <!-- 1.0 -->
+ <g transform="translate(34.696875 225.500467) scale(0.1 -0.1)">
+ <use xlink:href="#DejaVuSans-31"/>
<use xlink:href="#DejaVuSans-2e" x="63.623047"/>
- <use xlink:href="#DejaVuSans-34" x="95.410156"/>
+ <use xlink:href="#DejaVuSans-30" x="95.410156"/>
</g>
</g>
</g>
<g id="ytick_4">
<g id="line2d_7">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="175.812769" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m8afccf3ad6" x="57.6" y="178.759873" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_8">
- <!-- 0.6 -->
- <g transform="translate(34.696875 179.611988) scale(0.1 -0.1)">
- <defs>
- <path id="DejaVuSans-36" d="M 2113 2584
-Q 1688 2584 1439 2293
-Q 1191 2003 1191 1497
-Q 1191 994 1439 701
-Q 1688 409 2113 409
-Q 2538 409 2786 701
-Q 3034 994 3034 1497
-Q 3034 2003 2786 2293
-Q 2538 2584 2113 2584
-z
-M 3366 4563
-L 3366 3988
-Q 3128 4100 2886 4159
-Q 2644 4219 2406 4219
-Q 1781 4219 1451 3797
-Q 1122 3375 1075 2522
-Q 1259 2794 1537 2939
-Q 1816 3084 2150 3084
-Q 2853 3084 3261 2657
-Q 3669 2231 3669 1497
-Q 3669 778 3244 343
-Q 2819 -91 2113 -91
-Q 1303 -91 875 529
-Q 447 1150 447 2328
-Q 447 3434 972 4092
-Q 1497 4750 2381 4750
-Q 2619 4750 2861 4703
-Q 3103 4656 3366 4563
-z
-" transform="scale(0.015625)"/>
- </defs>
- <use xlink:href="#DejaVuSans-30"/>
+ <!-- 1.5 -->
+ <g transform="translate(34.696875 182.559091) scale(0.1 -0.1)">
+ <use xlink:href="#DejaVuSans-31"/>
<use xlink:href="#DejaVuSans-2e" x="63.623047"/>
- <use xlink:href="#DejaVuSans-36" x="95.410156"/>
+ <use xlink:href="#DejaVuSans-35" x="95.410156"/>
</g>
</g>
</g>
<g id="ytick_5">
<g id="line2d_8">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="131.889026" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m8afccf3ad6" x="57.6" y="135.818497" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_9">
- <!-- 0.8 -->
- <g transform="translate(34.696875 135.688245) scale(0.1 -0.1)">
+ <!-- 2.0 -->
+ <g transform="translate(34.696875 139.617716) scale(0.1 -0.1)">
<defs>
- <path id="DejaVuSans-38" d="M 2034 2216
-Q 1584 2216 1326 1975
-Q 1069 1734 1069 1313
-Q 1069 891 1326 650
-Q 1584 409 2034 409
-Q 2484 409 2743 651
-Q 3003 894 3003 1313
-Q 3003 1734 2745 1975
-Q 2488 2216 2034 2216
-z
-M 1403 2484
-Q 997 2584 770 2862
-Q 544 3141 544 3541
-Q 544 4100 942 4425
-Q 1341 4750 2034 4750
-Q 2731 4750 3128 4425
-Q 3525 4100 3525 3541
-Q 3525 3141 3298 2862
-Q 3072 2584 2669 2484
-Q 3125 2378 3379 2068
-Q 3634 1759 3634 1313
-Q 3634 634 3220 271
-Q 2806 -91 2034 -91
-Q 1263 -91 848 271
-Q 434 634 434 1313
-Q 434 1759 690 2068
-Q 947 2378 1403 2484
-z
-M 1172 3481
-Q 1172 3119 1398 2916
-Q 1625 2713 2034 2713
-Q 2441 2713 2670 2916
-Q 2900 3119 2900 3481
-Q 2900 3844 2670 4047
-Q 2441 4250 2034 4250
-Q 1625 4250 1398 4047
-Q 1172 3844 1172 3481
+ <path id="DejaVuSans-32" d="M 1228 531
+L 3431 531
+L 3431 0
+L 469 0
+L 469 531
+Q 828 903 1448 1529
+Q 2069 2156 2228 2338
+Q 2531 2678 2651 2914
+Q 2772 3150 2772 3378
+Q 2772 3750 2511 3984
+Q 2250 4219 1831 4219
+Q 1534 4219 1204 4116
+Q 875 4013 500 3803
+L 500 4441
+Q 881 4594 1212 4672
+Q 1544 4750 1819 4750
+Q 2544 4750 2975 4387
+Q 3406 4025 3406 3419
+Q 3406 3131 3298 2873
+Q 3191 2616 2906 2266
+Q 2828 2175 2409 1742
+Q 1991 1309 1228 531
z
" transform="scale(0.015625)"/>
</defs>
- <use xlink:href="#DejaVuSans-30"/>
+ <use xlink:href="#DejaVuSans-32"/>
<use xlink:href="#DejaVuSans-2e" x="63.623047"/>
- <use xlink:href="#DejaVuSans-38" x="95.410156"/>
+ <use xlink:href="#DejaVuSans-30" x="95.410156"/>
</g>
</g>
</g>
<g id="ytick_6">
<g id="line2d_9">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="87.965282" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m8afccf3ad6" x="57.6" y="92.877121" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_10">
- <!-- 1.0 -->
- <g transform="translate(34.696875 91.764501) scale(0.1 -0.1)">
- <use xlink:href="#DejaVuSans-31"/>
+ <!-- 2.5 -->
+ <g transform="translate(34.696875 96.67634) scale(0.1 -0.1)">
+ <use xlink:href="#DejaVuSans-32"/>
<use xlink:href="#DejaVuSans-2e" x="63.623047"/>
- <use xlink:href="#DejaVuSans-30" x="95.410156"/>
+ <use xlink:href="#DejaVuSans-35" x="95.410156"/>
</g>
</g>
</g>
<g id="ytick_7">
<g id="line2d_10">
<g>
- <use xlink:href="#meee343289d" x="57.6" y="44.041539" style="stroke:
#000000; stroke-width: 0.8"/>
+ <use xlink:href="#m8afccf3ad6" x="57.6" y="49.935745" style="stroke:
#000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_11">
- <!-- 1.2 -->
- <g transform="translate(34.696875 47.840758) scale(0.1 -0.1)">
- <use xlink:href="#DejaVuSans-31"/>
+ <!-- 3.0 -->
+ <g transform="translate(34.696875 53.734964) scale(0.1 -0.1)">
+ <defs>
+ <path id="DejaVuSans-33" d="M 2597 2516
+Q 3050 2419 3304 2112
+Q 3559 1806 3559 1356
+Q 3559 666 3084 287
+Q 2609 -91 1734 -91
+Q 1441 -91 1130 -33
+Q 819 25 488 141
+L 488 750
+Q 750 597 1062 519
+Q 1375 441 1716 441
+Q 2309 441 2620 675
+Q 2931 909 2931 1356
+Q 2931 1769 2642 2001
+Q 2353 2234 1838 2234
+L 1294 2234
+L 1294 2753
+L 1863 2753
+Q 2328 2753 2575 2939
+Q 2822 3125 2822 3475
+Q 2822 3834 2567 4026
+Q 2313 4219 1838 4219
+Q 1578 4219 1281 4162
+Q 984 4106 628 3988
+L 628 4550
+Q 988 4650 1302 4700
+Q 1616 4750 1894 4750
+Q 2613 4750 3031 4423
+Q 3450 4097 3450 3541
+Q 3450 3153 3228 2886
+Q 3006 2619 2597 2516
+z
+" transform="scale(0.015625)"/>
+ </defs>
+ <use xlink:href="#DejaVuSans-33"/>
<use xlink:href="#DejaVuSans-2e" x="63.623047"/>
- <use xlink:href="#DejaVuSans-32" x="95.410156"/>
+ <use xlink:href="#DejaVuSans-30" x="95.410156"/>
</g>
</g>
</g>
@@ -819,31 +786,31 @@ z
</g>
</g>
<g id="line2d_11">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_12">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_13">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_14">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_15">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_16">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_17">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_18">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="line2d_19">
- <path clip-path="url(#p3572019ee8)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
+ <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242;
stroke-width: 2.7; stroke-linecap: square"/>
</g>
<g id="patch_12">
<path d="M 57.6 307.584
@@ -1105,7 +1072,7 @@ z
" style="fill: #ff7f0e"/>
</g>
<g id="text_15">
- <!-- C -->
+ <!-- SELECT -->
<g transform="translate(94.6 87.426688) scale(0.1 -0.1)">
<defs>
<path id="DejaVuSans-43" d="M 4122 4306
@@ -1128,9 +1095,25 @@ Q 1578 4750 2638 4750
Q 3056 4750 3426 4639
Q 3797 4528 4122 4306
z
+" transform="scale(0.015625)"/>
+ <path id="DejaVuSans-54" d="M -19 4666
+L 3928 4666
+L 3928 4134
+L 2272 4134
+L 2272 0
+L 1638 0
+L 1638 4134
+L -19 4134
+L -19 4666
+z
" transform="scale(0.015625)"/>
</defs>
- <use xlink:href="#DejaVuSans-43"/>
+ <use xlink:href="#DejaVuSans-53"/>
+ <use xlink:href="#DejaVuSans-45" x="63.476562"/>
+ <use xlink:href="#DejaVuSans-4c" x="126.660156"/>
+ <use xlink:href="#DejaVuSans-45" x="182.373047"/>
+ <use xlink:href="#DejaVuSans-43" x="245.556641"/>
+ <use xlink:href="#DejaVuSans-54" x="315.380859"/>
</g>
</g>
<g id="patch_19">
@@ -1142,47 +1125,75 @@ z
" style="fill: #2ca02c"/>
</g>
<g id="text_16">
- <!-- psql -->
+ <!-- COPY -->
<g transform="translate(94.6 102.104813) scale(0.1 -0.1)">
<defs>
- <path id="DejaVuSans-71" d="M 947 1747
-Q 947 1113 1208 752
-Q 1469 391 1925 391
-Q 2381 391 2643 752
-Q 2906 1113 2906 1747
-Q 2906 2381 2643 2742
-Q 2381 3103 1925 3103
-Q 1469 3103 1208 2742
-Q 947 2381 947 1747
+ <path id="DejaVuSans-4f" d="M 2522 4238
+Q 1834 4238 1429 3725
+Q 1025 3213 1025 2328
+Q 1025 1447 1429 934
+Q 1834 422 2522 422
+Q 3209 422 3611 934
+Q 4013 1447 4013 2328
+Q 4013 3213 3611 3725
+Q 3209 4238 2522 4238
z
-M 2906 525
-Q 2725 213 2448 61
-Q 2172 -91 1784 -91
-Q 1150 -91 751 415
-Q 353 922 353 1747
-Q 353 2572 751 3078
-Q 1150 3584 1784 3584
-Q 2172 3584 2448 3432
-Q 2725 3281 2906 2969
-L 2906 3500
-L 3481 3500
-L 3481 -1331
-L 2906 -1331
-L 2906 525
+M 2522 4750
+Q 3503 4750 4090 4092
+Q 4678 3434 4678 2328
+Q 4678 1225 4090 567
+Q 3503 -91 2522 -91
+Q 1538 -91 948 565
+Q 359 1222 359 2328
+Q 359 3434 948 4092
+Q 1538 4750 2522 4750
+z
+" transform="scale(0.015625)"/>
+ <path id="DejaVuSans-50" d="M 1259 4147
+L 1259 2394
+L 2053 2394
+Q 2494 2394 2734 2622
+Q 2975 2850 2975 3272
+Q 2975 3691 2734 3919
+Q 2494 4147 2053 4147
+L 1259 4147
+z
+M 628 4666
+L 2053 4666
+Q 2838 4666 3239 4311
+Q 3641 3956 3641 3272
+Q 3641 2581 3239 2228
+Q 2838 1875 2053 1875
+L 1259 1875
+L 1259 0
+L 628 0
+L 628 4666
+z
+" transform="scale(0.015625)"/>
+ <path id="DejaVuSans-59" d="M -13 4666
+L 666 4666
+L 1959 2747
+L 3244 4666
+L 3922 4666
+L 2272 2222
+L 2272 0
+L 1638 0
+L 1638 2222
+L -13 4666
z
" transform="scale(0.015625)"/>
</defs>
- <use xlink:href="#DejaVuSans-70"/>
- <use xlink:href="#DejaVuSans-73" x="63.476562"/>
- <use xlink:href="#DejaVuSans-71" x="115.576172"/>
- <use xlink:href="#DejaVuSans-6c" x="179.052734"/>
+ <use xlink:href="#DejaVuSans-43"/>
+ <use xlink:href="#DejaVuSans-4f" x="69.824219"/>
+ <use xlink:href="#DejaVuSans-50" x="148.535156"/>
+ <use xlink:href="#DejaVuSans-59" x="206.587891"/>
</g>
</g>
</g>
</g>
</g>
<defs>
- <clipPath id="p3572019ee8">
+ <clipPath id="p3aca9fb4c4">
<rect x="57.6" y="41.472" width="357.12" height="266.112"/>
</clipPath>
</defs>
diff --git a/dev/release/rat_exclude_files.txt
b/dev/release/rat_exclude_files.txt
index 5d1761d..61c7482 100644
--- a/dev/release/rat_exclude_files.txt
+++ b/dev/release/rat_exclude_files.txt
@@ -15,8 +15,8 @@
# specific language governing permissions and limitations
# under the License.
-benchmark/integer/result.csv
-benchmark/integer/result.svg
+benchmark/*/result.csv
+benchmark/*/result.svg
compile_commands.json
dev/release/apache-rat-*.jar
dev/release/filtered_rat.txt
diff --git a/meson.build b/meson.build
index 103d51b..6226b9d 100644
--- a/meson.build
+++ b/meson.build
@@ -97,7 +97,7 @@ install_data(
)
if get_option('benchmark')
- subdir('benchmark/integer')
+ subdir('benchmark')
endif
if get_option('example')