mirror of
https://github.com/php-win-ext/grpc.git
synced 2026-03-26 01:52:16 +01:00
Introduce grpc_byte_buffer_reader_peek and use it for Protobuf parsing.
grpc_byte_buffer_reader_next() copies and references the slice. This
is not always necessary since the caller will not use the slice
after destroying the byte buffer.
A prominent example is the protobuf parser, which
calls grpc_byte_buffer_reader_next() and immediately unrefs the slice
after the call. This ref() and unref() calls can be very expensive
in the hot path.
This commit introduces grpc_byte_buffer_reader_peek() which
essentialy return a pointer to the slice in the buffer, i.e.,
no copies, and no refs.
QPS of 1MiB 1 Channel callback benchmark increases by 5%.
More importantly insructions per cycle is increased by 10%.
Also add tests and benchmarks for byte_buffer_reader_peek()
This commit reaplies 509e77a5a3
This commit is contained in:
@@ -29,9 +29,8 @@
|
||||
namespace grpc {
|
||||
namespace testing {
|
||||
|
||||
auto& force_library_initialization = Library::get();
|
||||
|
||||
static void BM_ByteBuffer_Copy(benchmark::State& state) {
|
||||
Library::get();
|
||||
int num_slices = state.range(0);
|
||||
size_t slice_size = state.range(1);
|
||||
std::vector<grpc::Slice> slices;
|
||||
@@ -48,6 +47,74 @@ static void BM_ByteBuffer_Copy(benchmark::State& state) {
|
||||
}
|
||||
BENCHMARK(BM_ByteBuffer_Copy)->Ranges({{1, 64}, {1, 1024 * 1024}});
|
||||
|
||||
static void BM_ByteBufferReader_Next(benchmark::State& state) {
|
||||
Library::get();
|
||||
const int num_slices = state.range(0);
|
||||
constexpr size_t kSliceSize = 16;
|
||||
std::vector<grpc_slice> slices;
|
||||
for (int i = 0; i < num_slices; ++i) {
|
||||
std::unique_ptr<char[]> buf(new char[kSliceSize]);
|
||||
slices.emplace_back(g_core_codegen_interface->grpc_slice_from_copied_buffer(
|
||||
buf.get(), kSliceSize));
|
||||
}
|
||||
grpc_byte_buffer* bb = g_core_codegen_interface->grpc_raw_byte_buffer_create(
|
||||
slices.data(), num_slices);
|
||||
grpc_byte_buffer_reader reader;
|
||||
GPR_ASSERT(
|
||||
g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb));
|
||||
while (state.KeepRunning()) {
|
||||
grpc_slice* slice;
|
||||
if (GPR_UNLIKELY(!g_core_codegen_interface->grpc_byte_buffer_reader_peek(
|
||||
&reader, &slice))) {
|
||||
g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader);
|
||||
GPR_ASSERT(
|
||||
g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader);
|
||||
g_core_codegen_interface->grpc_byte_buffer_destroy(bb);
|
||||
for (auto& slice : slices) {
|
||||
g_core_codegen_interface->grpc_slice_unref(slice);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_ByteBufferReader_Next)->Ranges({{64 * 1024, 1024 * 1024}});
|
||||
|
||||
static void BM_ByteBufferReader_Peek(benchmark::State& state) {
|
||||
Library::get();
|
||||
const int num_slices = state.range(0);
|
||||
constexpr size_t kSliceSize = 16;
|
||||
std::vector<grpc_slice> slices;
|
||||
for (int i = 0; i < num_slices; ++i) {
|
||||
std::unique_ptr<char[]> buf(new char[kSliceSize]);
|
||||
slices.emplace_back(g_core_codegen_interface->grpc_slice_from_copied_buffer(
|
||||
buf.get(), kSliceSize));
|
||||
}
|
||||
grpc_byte_buffer* bb = g_core_codegen_interface->grpc_raw_byte_buffer_create(
|
||||
slices.data(), num_slices);
|
||||
grpc_byte_buffer_reader reader;
|
||||
GPR_ASSERT(
|
||||
g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb));
|
||||
while (state.KeepRunning()) {
|
||||
grpc_slice* slice;
|
||||
if (GPR_UNLIKELY(!g_core_codegen_interface->grpc_byte_buffer_reader_peek(
|
||||
&reader, &slice))) {
|
||||
g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader);
|
||||
GPR_ASSERT(
|
||||
g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader);
|
||||
g_core_codegen_interface->grpc_byte_buffer_destroy(bb);
|
||||
for (auto& slice : slices) {
|
||||
g_core_codegen_interface->grpc_slice_unref(slice);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_ByteBufferReader_Peek)->Ranges({{64 * 1024, 1024 * 1024}});
|
||||
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
||||
|
||||
Reference in New Issue
Block a user