From 33e1f17dd195c0ad45c0e65aae4d97a04c782903 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Piotr=20Da=C5=82ek?= Date: Thu, 16 Jul 2015 10:18:54 +0200 Subject: [PATCH] buffer.cc: short-circuit in copy_out for small lengths MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For small lengths (1, 2, 4 and 8 bytes) use shorter code paths, this increases performance of function by around 40%. Signed-off-by: Piotr Dałek --- src/common/buffer.cc | 32 ++++++++++++++++++++++++++++++++ src/include/buffer.h | 7 +------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 294f9fc1bbaf3..90756d36364e5 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -781,6 +781,38 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER; unsigned buffer::ptr::raw_length() const { assert(_raw); return _raw->len; } int buffer::ptr::raw_nref() const { assert(_raw); return _raw->nref.read(); } + void buffer::ptr::copy_out(unsigned o, unsigned l, char *dest) const { + assert(_raw); + if (o+l > _len) + throw end_of_buffer(); + char* src = _raw->data + _off + o; + if (l > 8) { + memcpy(dest, src, l); + return; + } + switch (l) { + case 8: + *((uint64_t*)(dest)) = *((uint64_t*)(src)); + return; + case 4: + *((uint32_t*)(dest)) = *((uint32_t*)(src)); + return; + case 3: + *((uint16_t*)(dest)) = *((uint16_t*)(src)); + *((uint8_t*)(dest+2)) = *((uint8_t*)(src+2)); + return; + case 2: + *((uint16_t*)(dest)) = *((uint16_t*)(src)); + return; + case 1: + *((uint8_t*)(dest)) = *((uint8_t*)(src)); + return; + default: + memcpy(dest, src, l); + return; + } + } + unsigned buffer::ptr::wasted() { assert(_raw); diff --git a/src/include/buffer.h b/src/include/buffer.h index 3ff04063783ae..70f00180b0c1e 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -219,12 +219,7 @@ public: unsigned raw_length() const; int raw_nref() const; - void copy_out(unsigned o, unsigned l, char *dest) const { - assert(_raw); - if (!((o <= _len) && (o+l <= _len))) - throw end_of_buffer(); - memcpy(dest, c_str()+o, l); - } + void copy_out(unsigned o, unsigned l, char *dest) const; bool can_zero_copy() const; int zero_copy_to_fd(int fd, int64_t *offset) const; -- 2.39.5