| 33 | static constexpr int64_t kSize = 100000; |
| 34 | |
| 35 | void SpscQueueThroughput(benchmark::State& state) { |
| 36 | SpscQueue<std::shared_ptr<Buffer>> queue(16); |
| 37 | |
| 38 | std::vector<std::shared_ptr<Buffer>> source; |
| 39 | std::vector<std::shared_ptr<Buffer>> sink; |
| 40 | source.reserve(kSize); |
| 41 | sink.resize(kSize); |
| 42 | const uint8_t data[1] = {0}; |
| 43 | for (int64_t i = 0; i < kSize; i++) { |
| 44 | source.push_back(std::make_shared<Buffer>(data, 1)); |
| 45 | } |
| 46 | |
| 47 | for (auto _ : state) { |
| 48 | std::thread producer([&] { |
| 49 | auto itr = std::make_move_iterator(source.begin()); |
| 50 | auto end = std::make_move_iterator(source.end()); |
| 51 | while (itr != end) { |
| 52 | while (!queue.Write(*itr)) { |
| 53 | } |
| 54 | itr++; |
| 55 | } |
| 56 | }); |
| 57 | |
| 58 | std::thread consumer([&] { |
| 59 | auto itr = sink.begin(); |
| 60 | auto end = sink.end(); |
| 61 | while (itr != end) { |
| 62 | auto next = queue.FrontPtr(); |
| 63 | if (next != nullptr) { |
| 64 | (*itr).swap(*next); |
| 65 | queue.PopFront(); |
| 66 | itr++; |
| 67 | } |
| 68 | } |
| 69 | }); |
| 70 | |
| 71 | producer.join(); |
| 72 | consumer.join(); |
| 73 | std::swap(source, sink); |
| 74 | } |
| 75 | |
| 76 | for (const auto& buf : source) { |
| 77 | ARROW_CHECK(buf && buf->size() == 1); |
| 78 | } |
| 79 | state.SetItemsProcessed(state.iterations() * kSize); |
| 80 | } |
| 81 | |
| 82 | BENCHMARK(SpscQueueThroughput)->UseRealTime(); |
| 83 | |