From af1e4a5c363e87d364d400227a1892af5a75656d Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Sun, 19 Nov 2023 07:19:07 +0900 Subject: [PATCH] Add missing build time for INSERT/COPY with PostgreSQL protocol Closes GH-171 --- benchmark/insert-copy.cc | 119 +++++++++------ benchmark/insert.cc | 92 ++++++------ benchmark/insert.hh | 92 ++++++++++++ benchmark/integer/README.md | 12 +- benchmark/integer/insert.csv | 18 +-- benchmark/integer/insert.svg | 104 ++++++------- benchmark/integer/select.csv | 12 +- benchmark/integer/select.svg | 112 +++++++------- benchmark/select-copy.c | 9 +- benchmark/select-polars.py | 1 - benchmark/select.c | 2 +- benchmark/string/README.md | 12 +- benchmark/string/insert.csv | 18 +-- benchmark/string/insert.svg | 133 ++++++++--------- benchmark/string/select.csv | 16 +- benchmark/string/select.svg | 281 ++++++++++++++++++++++------------- 16 files changed, 607 insertions(+), 426 deletions(-) create mode 100644 benchmark/insert.hh diff --git a/benchmark/insert-copy.cc b/benchmark/insert-copy.cc index d2f8165..7bb3957 100644 --- a/benchmark/insert-copy.cc +++ b/benchmark/insert-copy.cc @@ -17,30 +17,18 @@ * under the License. */ -#include -#include -#include -#include +#include "insert.hh" -#include +#include -class ConnectionFinisher { - public: - ConnectionFinisher(PGconn* connection) : connection_(connection) {} - ~ConnectionFinisher() { PQfinish(connection_); } - - private: - PGconn* connection_; -}; - -class ResultClearner { - public: - ResultClearner(PGresult* result) : result_(result) {} - ~ResultClearner() { PQclear(result_); } - - private: - PGresult* result_; -}; +namespace { +template +void +write_binary_data(std::ostream& stream, Type value) +{ + stream.write(reinterpret_cast(&value), sizeof(Type)); +} +}; // namespace int main(int argc, char** argv) @@ -78,33 +66,31 @@ main(int argc, char** argv) } } - std::vector buffers; + std::vector> records; { - auto result = PQexec(connection, "COPY data TO STDOUT (FORMAT binary)"); + auto result = PQexec(connection, "SELECT * FROM data"); ResultClearner resultClearner(result); - if (PQresultStatus(result) != PGRES_COPY_OUT) + if (PQresultStatus(result) != PGRES_TUPLES_OK) { - std::cerr << "failed to copy to: " << PQerrorMessage(connection) << std::endl; + std::cerr << "failed to select: " << PQerrorMessage(connection) << std::endl; return EXIT_FAILURE; } - while (true) + auto nTuples = PQntuples(result); + auto nFields = PQnfields(result); + for (int iTuple = 0; iTuple < nTuples; iTuple++) { - char* data; - auto size = PQgetCopyData(connection, &data, 0); - if (size == -1) - { - break; - } - if (size == -2) + std::vector values; + for (int iField = 0; iField < nFields; iField++) { - std::cerr << "failed to read copy data: " << PQerrorMessage(connection) - << std::endl; - return EXIT_FAILURE; + if (!append_value(values, result, iTuple, iField)) + { + return EXIT_FAILURE; + } } - buffers.emplace_back(data, size); - free(data); + records.push_back(std::move(values)); } } + auto before = std::chrono::steady_clock::now(); { auto result = PQexec(connection, "COPY data_insert FROM STDOUT (FORMAT binary)"); @@ -115,15 +101,58 @@ main(int argc, char** argv) << std::endl; return EXIT_FAILURE; } - for (const auto& buffer : buffers) + std::ostringstream copyDataStream; { - auto copyDataResult = PQputCopyData(connection, buffer.data(), buffer.size()); - if (copyDataResult == -1) + // See the "Binary Format" section in + // https://www.postgresql.org/docs/current/sql-copy.html for + // details. + + const char signature[] = "PGCOPY\n\377\r\n"; + // The last '\0' is also part of the signature. + copyDataStream << std::string_view(signature, sizeof(signature)); + const uint32_t flags = 0; + write_binary_data(copyDataStream, htonl(flags)); + const uint32_t headerExtensionAreaLength = 0; + write_binary_data(copyDataStream, htonl(headerExtensionAreaLength)); + auto nRecords = records.size(); + for (size_t iRecord = 0; iRecord < nRecords; ++iRecord) { - std::cerr << "failed to put copy data: " << PQerrorMessage(connection) - << std::endl; - return EXIT_FAILURE; + const auto& values = records[iRecord]; + const auto nValues = values.size(); + write_binary_data(copyDataStream, htons(nValues)); + for (size_t iValue = 0; iValue < nValues; ++iValue) + { + const auto& value = values[iValue]; + if (std::holds_alternative(value)) + { + write_binary_data(copyDataStream, + htonl(static_cast(-1))); + } + else if (std::holds_alternative(value)) + { + const auto& int32Value = std::get(value); + write_binary_data(copyDataStream, htonl(sizeof(int32_t))); + write_binary_data(copyDataStream, + htonl(static_cast(int32Value))); + } + else if (std::holds_alternative(value)) + { + const auto& stringValue = std::get(value); + write_binary_data(copyDataStream, htonl(stringValue.size())); + copyDataStream << stringValue; + } + } } + const uint16_t fileTrailer = -1; + write_binary_data(copyDataStream, htons(fileTrailer)); + } + const auto& copyData = copyDataStream.str(); + auto copyDataResult = PQputCopyData(connection, copyData.data(), copyData.size()); + if (copyDataResult == -1) + { + std::cerr << "failed to put copy data: " << PQerrorMessage(connection) + << std::endl; + return EXIT_FAILURE; } auto copyEndResult = PQputCopyEnd(connection, nullptr); if (copyEndResult == -1) diff --git a/benchmark/insert.cc b/benchmark/insert.cc index 7eb58f5..4ffecb8 100644 --- a/benchmark/insert.cc +++ b/benchmark/insert.cc @@ -17,31 +17,7 @@ * under the License. */ -#include -#include -#include - -#include - -#include - -class ConnectionFinisher { - public: - ConnectionFinisher(PGconn* connection) : connection_(connection) {} - ~ConnectionFinisher() { PQfinish(connection_); } - - private: - PGconn* connection_; -}; - -class ResultClearner { - public: - ResultClearner(PGresult* result) : result_(result) {} - ~ResultClearner() { PQclear(result_); } - - private: - PGresult* result_; -}; +#include "insert.hh" int main(int argc, char** argv) @@ -79,7 +55,7 @@ main(int argc, char** argv) } } - std::string insert = "INSERT INTO data_insert VALUES "; + std::vector> records; { auto result = PQexec(connection, "SELECT * FROM data"); ResultClearner resultClearner(result); @@ -92,37 +68,57 @@ main(int argc, char** argv) auto nFields = PQnfields(result); for (int iTuple = 0; iTuple < nTuples; iTuple++) { - if (iTuple > 0) - { - insert += ", "; - } + std::vector values; for (int iField = 0; iField < nFields; iField++) { - if (PQgetisnull(result, iTuple, iField)) - { - insert += "(null)"; - } - else + if (!append_value(values, result, iTuple, iField)) { - insert += "("; - auto type = PQftype(result, iField); - if (type == TEXTOID) - { - insert += "'"; - } - insert += PQgetvalue(result, iTuple, iField); - if (type == TEXTOID) - { - insert += "'"; - } - insert += ")"; + return EXIT_FAILURE; } } + records.push_back(std::move(values)); } } + auto before = std::chrono::steady_clock::now(); { - auto result = PQexec(connection, insert.c_str()); + std::ostringstream insert; + insert << "INSERT INTO data_insert VALUES "; + auto nRecords = records.size(); + for (size_t iRecord = 0; iRecord < nRecords; ++iRecord) + { + const auto& values = records[iRecord]; + if (iRecord > 0) + { + insert << ", "; + } + insert << "("; + auto nValues = values.size(); + for (size_t iValue = 0; iValue < nValues; ++iValue) + { + if (iValue > 0) + { + insert << ", "; + } + const auto& value = values[iValue]; + if (std::holds_alternative(value)) + { + insert << "null"; + } + else if (std::holds_alternative(value)) + { + insert << std::get(value); + } + else if (std::holds_alternative(value)) + { + insert << "'"; + insert << std::get(value); + insert << "'"; + } + } + insert << ")"; + } + auto result = PQexec(connection, insert.str().c_str()); ResultClearner resultClearner(result); if (PQresultStatus(result) != PGRES_COMMAND_OK) { diff --git a/benchmark/insert.hh b/benchmark/insert.hh new file mode 100644 index 0000000..14c02c2 --- /dev/null +++ b/benchmark/insert.hh @@ -0,0 +1,92 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace { +class ConnectionFinisher { + public: + ConnectionFinisher(PGconn* connection) : connection_(connection) {} + ~ConnectionFinisher() { PQfinish(connection_); } + + private: + PGconn* connection_; +}; + +class ResultClearner { + public: + ResultClearner(PGresult* result) : result_(result) {} + ~ResultClearner() { PQclear(result_); } + + private: + PGresult* result_; +}; + +using Value = std::variant; + +bool +append_value(std::vector& values, PGresult* result, int iTuple, int iField) +{ + if (PQgetisnull(result, iTuple, iField)) + { + values.push_back(std::monostate{}); + return true; + } + + Oid type = PQftype(result, iField); + char* rawValue = PQgetvalue(result, iTuple, iField); + int length = PQgetlength(result, iTuple, iField); + switch (type) + { + case INT4OID: + { + int32_t value; + auto result = std::from_chars(rawValue, rawValue + length, value); + if (result.ec != std::errc{}) + { + std::cerr << "failed to parse integer value: " << rawValue << std::endl; + return false; + } + values.emplace_back(value); + } + break; + case TEXTOID: + { + values.emplace_back(std::string(rawValue, length)); + } + break; + default: + std::cerr << "unsupported type: " << type << std::endl; + return false; + } + return true; +} +}; // namespace diff --git a/benchmark/integer/README.md b/benchmark/integer/README.md index 60e7a7c..5f72318 100644 --- a/benchmark/integer/README.md +++ b/benchmark/integer/README.md @@ -48,19 +48,19 @@ Here is a benchmark result on the following environment: | Apache Arrow Flight SQL | `SELECT` | `COPY` | | ----------------------- | -------- | ------ | -| 0.014 | 0.015 | 0.011 | +| 0.014 | 0.015 | 0.012 | 1M records: | Apache Arrow Flight SQL | `SELECT` | `COPY` | | ----------------------- | -------- | ------ | -| 0.082 | 0.145 | 0.110 | +| 0.082 | 0.140 | 0.112 | 10M records: | Apache Arrow Flight SQL | `SELECT` | `COPY` | | ----------------------- | -------- | ------ | -| 0.694 | 1.486 | 1.142 | +| 0.691 | 1.463 | 1.108 | ### `INSERT` @@ -70,16 +70,16 @@ Here is a benchmark result on the following environment: | Apache Arrow Flight SQL | `INSERT` | `COPY` | | ----------------------- | -------- | ------ | -| 0.273 | 0.121 | 0.020 | +| 0.497 | 0.310 | 0.068 | 1M records: | Apache Arrow Flight SQL | `INSERT` | `COPY` | | ----------------------- | -------- | ------ | -| 6.055 | 2.232 | 0.345 | +| 7.013 | 5.410 | 0.637 | 10M records: | Apache Arrow Flight SQL | `INSERT` | `COPY` | | ----------------------- | -------- | ------ | -| 51.757 | 31.390 | 7.832 | +| 55.064 | 37.522 | 6.720 | diff --git a/benchmark/integer/insert.csv b/benchmark/integer/insert.csv index 068c12c..5958741 100644 --- a/benchmark/integer/insert.csv +++ b/benchmark/integer/insert.csv @@ -1,10 +1,10 @@ Approach,N records,Elapsed time (sec) -Apache Arrow Flight SQL,100000,0.273 -INSERT,100000,0.121 -COPY,100000,0.020 -Apache Arrow Flight SQL,1000000,6.055 -INSERT,1000000,2.232 -COPY,1000000,0.345 -Apache Arrow Flight SQL,10000000,51.757 -INSERT,10000000,31.390 -COPY,10000000,7.832 +Apache Arrow Flight SQL,100000,0.497 +INSERT,100000,0.310 +COPY,100000,0.068 +Apache Arrow Flight SQL,1000000,7.013 +INSERT,1000000,5.410 +COPY,1000000,0.637 +Apache Arrow Flight SQL,10000000,55.064 +INSERT,10000000,37.522 +COPY,10000000,6.720 diff --git a/benchmark/integer/insert.svg b/benchmark/integer/insert.svg index edae65a..dfde81a 100644 --- a/benchmark/integer/insert.svg +++ b/benchmark/integer/insert.svg @@ -6,7 +6,7 @@ - 2023-11-16T18:51:19.434953 + 2023-11-19T07:16:29.203133 image/svg+xml @@ -40,18 +40,18 @@ z +" clip-path="url(#pea0638fa9b)" style="fill: #1f77b4"/> +" clip-path="url(#pea0638fa9b)" style="fill: #1f77b4"/> +" clip-path="url(#pea0638fa9b)" style="fill: #1f77b4"/> +" clip-path="url(#pea0638fa9b)" style="fill: #ff7f0e"/> +" clip-path="url(#pea0638fa9b)" style="fill: #ff7f0e"/> +" clip-path="url(#pea0638fa9b)" style="fill: #ff7f0e"/> +" clip-path="url(#pea0638fa9b)" style="fill: #2ca02c"/> +" clip-path="url(#pea0638fa9b)" style="fill: #2ca02c"/> +" clip-path="url(#pea0638fa9b)" style="fill: #2ca02c"/> - - + @@ -173,7 +173,7 @@ z - + @@ -192,7 +192,7 @@ z - + @@ -385,12 +385,12 @@ z - - + @@ -403,12 +403,12 @@ L -3.5 0 - + - + @@ -417,12 +417,12 @@ L -3.5 0 - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + diff --git a/benchmark/integer/select.csv b/benchmark/integer/select.csv index 90fec54..9c4c251 100644 --- a/benchmark/integer/select.csv +++ b/benchmark/integer/select.csv @@ -1,10 +1,10 @@ Approach,N records,Elapsed time (sec) Apache Arrow Flight SQL,100000,0.014 SELECT,100000,0.015 -COPY,100000,0.011 +COPY,100000,0.012 Apache Arrow Flight SQL,1000000,0.082 -SELECT,1000000,0.145 -COPY,1000000,0.110 -Apache Arrow Flight SQL,10000000,0.694 -SELECT,10000000,1.486 -COPY,10000000,1.142 +SELECT,1000000,0.140 +COPY,1000000,0.112 +Apache Arrow Flight SQL,10000000,0.691 +SELECT,10000000,1.463 +COPY,10000000,1.108 diff --git a/benchmark/integer/select.svg b/benchmark/integer/select.svg index 8703293..afcab04 100644 --- a/benchmark/integer/select.svg +++ b/benchmark/integer/select.svg @@ -6,7 +6,7 @@ - 2023-11-16T18:51:19.944464 + 2023-11-19T07:16:29.366290 image/svg+xml @@ -40,42 +40,42 @@ z +" clip-path="url(#p84ae3e9eea)" style="fill: #1f77b4"/> +" clip-path="url(#p84ae3e9eea)" style="fill: #1f77b4"/> +" clip-path="url(#p84ae3e9eea)" style="fill: #1f77b4"/> +" clip-path="url(#p84ae3e9eea)" style="fill: #ff7f0e"/> +" clip-path="url(#p84ae3e9eea)" style="fill: #ff7f0e"/> +" clip-path="url(#p84ae3e9eea)" style="fill: #ff7f0e"/> +" clip-path="url(#p84ae3e9eea)" style="fill: #2ca02c"/> +" clip-path="url(#p84ae3e9eea)" style="fill: #2ca02c"/> +" clip-path="url(#p84ae3e9eea)" style="fill: #2ca02c"/> - - + @@ -173,7 +173,7 @@ z - + @@ -192,7 +192,7 @@ z - + @@ -385,12 +385,12 @@ z - - + @@ -414,12 +414,12 @@ z - + - + - + - + - + - + - + - + - + - + @@ -609,12 +609,12 @@ z - + - + @@ -624,12 +624,12 @@ z - + - + @@ -834,31 +834,31 @@ z - + - + - + - + - + - + - + - + - + + diff --git a/benchmark/select-copy.c b/benchmark/select-copy.c index 11ad095..8d27fcf 100644 --- a/benchmark/select-copy.c +++ b/benchmark/select-copy.c @@ -31,8 +31,9 @@ /* 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 char signature[11] = "PGCOPY\n\377\r\n"; static const size_t signatureSize = sizeof(signature); typedef struct { @@ -53,7 +54,7 @@ read_uint16(Buffer* buffer, uint16_t* output, const char* tag) return false; } - *output = htons(*((uint16_t*)(buffer->data))); + *output = ntohs(*((uint16_t*)(buffer->data))); buffer->data += sizeof(uint16_t); buffer->size -= sizeof(uint16_t); return true; @@ -72,7 +73,7 @@ read_uint32(Buffer* buffer, uint32_t* output, const char* tag) return false; } - *output = htonl(*((uint32_t*)(buffer->data))); + *output = ntohl(*((uint32_t*)(buffer->data))); buffer->data += sizeof(uint32_t); buffer->size -= sizeof(uint32_t); return true; @@ -176,7 +177,7 @@ parse_tuples(Buffer* buffer, Oid* types, bool* finished) } default: fprintf(stderr, - "tuple: field: %u: Unsupported type: %u: %u: %d\n", + "tuple: field: %u: unsupported type: %u: %u: %d\n", i, type, size, diff --git a/benchmark/select-polars.py b/benchmark/select-polars.py index 652674a..33f6d5c 100755 --- a/benchmark/select-polars.py +++ b/benchmark/select-polars.py @@ -32,4 +32,3 @@ polars.read_database_uri(query="SELECT * FROM data", uri=uri) print(time.perf_counter() - start) - diff --git a/benchmark/select.c b/benchmark/select.c index 7711bee..fcc66fa 100644 --- a/benchmark/select.c +++ b/benchmark/select.c @@ -55,7 +55,7 @@ parse_value(PGresult* result, int iTuple, int iField) } break; default: - fprintf(stderr, "Unsupported type: %u\n", type); + fprintf(stderr, "unsupported type: %u\n", type); return false; } return true; diff --git a/benchmark/string/README.md b/benchmark/string/README.md index d0f2594..48c8426 100644 --- a/benchmark/string/README.md +++ b/benchmark/string/README.md @@ -48,19 +48,19 @@ Here is a benchmark result on the following environment: | Apache Arrow Flight SQL | `SELECT` | `COPY` | | ----------------------- | -------- | ------ | -| 0.041 | 0.016 | 0.016 | +| 0.040 | 0.017 | 0.016 | 1M records: | Apache Arrow Flight SQL | `SELECT` | `COPY` | | ----------------------- | -------- | ------ | -| 0.353 | 0.149 | 0.148 | +| 0.364 | 0.162 | 0.152 | 10M records: | Apache Arrow Flight SQL | `SELECT` | `COPY` | | ----------------------- | -------- | ------ | -| 2.154 | 1.924 | 1.596 | +| 2.053 | 1.706 | 1.603 | ### `INSERT` @@ -70,16 +70,16 @@ Here is a benchmark result on the following environment: | Apache Arrow Flight SQL | `INSERT` | `COPY` | | ----------------------- | -------- | ------ | -| 0.343 | 0.338 | 0.416 | +| 0.661 | 0.622 | 0.265 | 1M records: | Apache Arrow Flight SQL | `INSERT` | `COPY` | | ----------------------- | -------- | ------ | -| 6.906 | 5.730 | 2.870 | +| 7.028 | 5.956 | 2.915 | 10M records: | Apache Arrow Flight SQL | `INSERT` | `COPY` | | ----------------------- | -------- | ------ | -| 116.579 | 107.045 | 66.410 | +| 97.898 | 86.678 | 50.889 | diff --git a/benchmark/string/insert.csv b/benchmark/string/insert.csv index 73f8bb7..d6f01ef 100644 --- a/benchmark/string/insert.csv +++ b/benchmark/string/insert.csv @@ -1,10 +1,10 @@ Approach,N records,Elapsed time (sec) -Apache Arrow Flight SQL,100000,0.343 -INSERT,100000,0.338 -COPY,100000,0.416 -Apache Arrow Flight SQL,1000000,6.906 -INSERT,1000000,5.730 -COPY,1000000,2.870 -Apache Arrow Flight SQL,10000000,116.579 -INSERT,10000000,107.045 -COPY,10000000,66.410 +Apache Arrow Flight SQL,100000,0.661 +INSERT,100000,0.622 +COPY,100000,0.265 +Apache Arrow Flight SQL,1000000,7.028 +INSERT,1000000,5.956 +COPY,1000000,2.915 +Apache Arrow Flight SQL,10000000,97.898 +INSERT,10000000,86.678 +COPY,10000000,50.889 diff --git a/benchmark/string/insert.svg b/benchmark/string/insert.svg index cb8e05a..3c65bd7 100644 --- a/benchmark/string/insert.svg +++ b/benchmark/string/insert.svg @@ -6,7 +6,7 @@ - 2023-11-16T18:51:20.038826 + 2023-11-19T07:16:29.455651 image/svg+xml @@ -40,18 +40,18 @@ z +" clip-path="url(#p9bc037ba06)" style="fill: #1f77b4"/> +" clip-path="url(#p9bc037ba06)" style="fill: #1f77b4"/> +" clip-path="url(#p9bc037ba06)" style="fill: #1f77b4"/> +" clip-path="url(#p9bc037ba06)" style="fill: #ff7f0e"/> +" clip-path="url(#p9bc037ba06)" style="fill: #ff7f0e"/> +" clip-path="url(#p9bc037ba06)" style="fill: #ff7f0e"/> +" clip-path="url(#p9bc037ba06)" style="fill: #2ca02c"/> +" clip-path="url(#p9bc037ba06)" style="fill: #2ca02c"/> +" clip-path="url(#p9bc037ba06)" style="fill: #2ca02c"/> - - + @@ -173,7 +173,7 @@ z - + @@ -192,7 +192,7 @@ z - + @@ -385,12 +385,12 @@ z - - + @@ -403,12 +403,12 @@ L -3.5 0 - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - + @@ -803,32 +788,32 @@ z + + + - + - + - + - + - + - + - + - - - - + - + @@ -922,7 +907,7 @@ L 66.6 65.748563 z " style="fill: #1f77b4"/> - + @@ -1089,7 +1074,7 @@ L 66.6 80.426688 z " style="fill: #ff7f0e"/> - + @@ -1156,7 +1141,7 @@ L 66.6 95.104813 z " style="fill: #2ca02c"/> - + @@ -1246,7 +1231,7 @@ z - + diff --git a/benchmark/string/select.csv b/benchmark/string/select.csv index 8053df9..bd56dbf 100644 --- a/benchmark/string/select.csv +++ b/benchmark/string/select.csv @@ -1,10 +1,10 @@ Approach,N records,Elapsed time (sec) -Apache Arrow Flight SQL,100000,0.041 -SELECT,100000,0.016 +Apache Arrow Flight SQL,100000,0.040 +SELECT,100000,0.017 COPY,100000,0.016 -Apache Arrow Flight SQL,1000000,0.353 -SELECT,1000000,0.149 -COPY,1000000,0.148 -Apache Arrow Flight SQL,10000000,2.154 -SELECT,10000000,1.924 -COPY,10000000,1.596 +Apache Arrow Flight SQL,1000000,0.364 +SELECT,1000000,0.162 +COPY,1000000,0.152 +Apache Arrow Flight SQL,10000000,2.053 +SELECT,10000000,1.706 +COPY,10000000,1.603 diff --git a/benchmark/string/select.svg b/benchmark/string/select.svg index e937061..f246230 100644 --- a/benchmark/string/select.svg +++ b/benchmark/string/select.svg @@ -6,7 +6,7 @@ - 2023-11-16T18:51:20.134370 + 2023-11-19T07:16:29.547253 image/svg+xml @@ -40,18 +40,18 @@ z +" clip-path="url(#p0b9328f81d)" style="fill: #1f77b4"/> +" clip-path="url(#p0b9328f81d)" style="fill: #1f77b4"/> +" clip-path="url(#p0b9328f81d)" style="fill: #1f77b4"/> +" clip-path="url(#p0b9328f81d)" style="fill: #ff7f0e"/> +" clip-path="url(#p0b9328f81d)" style="fill: #ff7f0e"/> +" clip-path="url(#p0b9328f81d)" style="fill: #ff7f0e"/> +" clip-path="url(#p0b9328f81d)" style="fill: #2ca02c"/> +" clip-path="url(#p0b9328f81d)" style="fill: #2ca02c"/> +" clip-path="url(#p0b9328f81d)" style="fill: #2ca02c"/> - - + @@ -173,7 +173,7 @@ z - + @@ -192,7 +192,7 @@ z - + @@ -385,17 +385,17 @@ z - - + - - + + + - + - - + + + - + + - + - - - + + + - + + - + - - - + + + + + + - + + - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - - - - - + - + - + - + - + + + + + + + + + + + + + - + @@ -840,7 +919,7 @@ L 66.6 65.748563 z " style="fill: #1f77b4"/> - + @@ -1007,7 +1086,7 @@ L 66.6 80.426688 z " style="fill: #ff7f0e"/> - + @@ -1060,7 +1139,7 @@ L 66.6 95.104813 z " style="fill: #2ca02c"/> - + @@ -1129,7 +1208,7 @@ z - +