| /* |
| * 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 <chrono> |
| #include <cmath> |
| #include <iostream> |
| #include <numeric> |
| #include <string> |
| |
| #include "bench_conf.h" |
| #include "common/db_common.h" |
| #include "common/global.h" |
| #include "common/path.h" |
| #include "writer/tsfile_writer.h" |
| |
| std::vector<int> register_timeseries(storage::TsFileWriter& writer, |
| int timeseries_num, |
| std::vector<int> type_list) { |
| auto start = std::chrono::high_resolution_clock::now(); |
| int sum = std::accumulate(type_list.begin(), type_list.end(), 0); |
| std::vector<float> ratio_list; |
| for (int i = 0; i < type_list.size(); i++) { |
| ratio_list.push_back((float)type_list[i] / sum); |
| } |
| std::vector<int> type_num; |
| for (int i = 0; i < common::TSDataType::TEXT - 1; i++) { |
| type_num.push_back((int)std::ceil(timeseries_num * ratio_list[i])); |
| } |
| type_num.push_back(timeseries_num - |
| std::accumulate(type_num.begin(), type_num.end(), 0)); |
| writer.open("/tmp/tsfile_test.tsfile", O_CREAT | O_RDWR, 0644); |
| int ind = 0; |
| int ret = 0; |
| int type = 0; |
| for (auto num : type_num) { |
| for (int i = 0; i < num; i++) { |
| std::string device_name = "root.db001.dev" + std::to_string(ind); |
| std::string measurement_name = "m" + std::to_string(ind); |
| ret = writer.register_timeseries( |
| device_name, measurement_name, (common::TSDataType)type, |
| common::TSEncoding::PLAIN, |
| common::CompressionType::UNCOMPRESSED); |
| ind++; |
| } |
| std::cout << "register finished for TsDataType" |
| << common::s_data_type_names[type] |
| << " timeseries num: " << num << std::endl; |
| type++; |
| } |
| auto end = std::chrono::high_resolution_clock::now(); |
| std::chrono::duration<double> elapsed = end - start; |
| std::cout << "register " << timeseries_num << "timeseries in file" |
| << "./test_data/tsfile_test.tsfile" << std::endl; |
| std::cout << "register timeseries cost time: " << elapsed.count() << "s" |
| << std::endl; |
| return type_num; |
| } |
| |
| void test_writer_benchmark(storage::TsFileWriter& writer, int loop_num, |
| std::vector<int> type_num) { |
| std::cout << "start writing data" << std::endl; |
| auto start = std::chrono::high_resolution_clock::now(); |
| int type = 0; |
| for (int i = 0; i < loop_num; i++) { |
| int ind = 0; |
| for (auto num : type_num) { |
| for (int j = 0; j < num; j++) { |
| std::string device_name = |
| "root.db001.dev" + std::to_string(ind); |
| std::string measurement_name = "m" + std::to_string(ind); |
| long long currentTimeStamp = i; |
| storage::TsRecord record(currentTimeStamp, device_name, 1); |
| switch (type) { |
| case common::INT32: { |
| storage::DataPoint point(measurement_name, 10000 + i); |
| record.points_.push_back(point); |
| break; |
| } |
| case common::INT64: { |
| storage::DataPoint point(measurement_name, |
| int64_t(10000 + i)); |
| record.points_.push_back(point); |
| break; |
| } |
| case common::BOOLEAN: { |
| storage::DataPoint point(measurement_name, i / 2 == 0); |
| record.points_.push_back(point); |
| break; |
| } |
| case common::FLOAT: { |
| storage::DataPoint point(measurement_name, (float)i); |
| record.points_.push_back(point); |
| break; |
| } |
| case common::DOUBLE: { |
| storage::DataPoint point(measurement_name, (double)i); |
| record.points_.push_back(point); |
| break; |
| } |
| } |
| int ret = writer.write_record(record); |
| ASSERT(ret == 0); |
| ind++; |
| } |
| type++; |
| } |
| } |
| |
| auto end = std::chrono::high_resolution_clock::now(); |
| std::chrono::duration<double> elapsed = end - start; |
| int timeseries_num = std::accumulate(type_num.begin(), type_num.end(), 0); |
| std::cout << "writer loop: " << loop_num |
| << " timeseries num: " << timeseries_num << " records in file" |
| << "./test_data/tsfile_test.tsfile" << std::endl; |
| std::cout << "total num of points: " << loop_num * timeseries_num |
| << std::endl; |
| std::cout << "writer data cost time: " << elapsed.count() << "s" |
| << std::endl; |
| std::cout << "writer data speed:" |
| << loop_num * timeseries_num / elapsed.count() << " points/s" |
| << std::endl; |
| writer.flush(); |
| writer.close(); |
| auto end_flush = std::chrono::high_resolution_clock::now(); |
| std::chrono::duration<double> elapsed_flush = end_flush - end; |
| std::cout << "flush data cost time: " << elapsed_flush.count() << "s" |
| << std::endl; |
| } |
| |
| int main() { |
| std::cout << "LibTsFile benchmark" << std::endl; |
| std::cout << "LOOP_NUM:" << bench::LOOP_NUM << std::endl; |
| std::cout << "THREAD_NUM:" << bench::THREAD_NUM << std::endl; |
| std::cout << "TIMESERIES_NUM:" << bench::TIMESERIES_NUM << std::endl; |
| std::cout << "TYPE_LIST: " << bench::TYPE_LIST[0] << ":" |
| << bench::TYPE_LIST[1] << ":" << bench::TYPE_LIST[2] << ":" |
| << bench::TYPE_LIST[3] << ":" << bench::TYPE_LIST[4] << ":" |
| << bench::TYPE_LIST[5] << std::endl; |
| std::cout << "init tsfile config value" << std::endl; |
| common::init_config_value(); |
| storage::TsFileWriter writer; |
| auto type_num = |
| register_timeseries(writer, bench::TIMESERIES_NUM, bench::TYPE_LIST); |
| test_writer_benchmark(writer, bench::LOOP_NUM, type_num); |
| return 0; |
| } |