From 311ef972cc1f794969459302b08e3de403ce7e06 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Piotr=20Da=C5=82ek?= Date: Thu, 16 Jul 2015 11:19:37 +0200 Subject: [PATCH] buffer.cc: short-circuit copy_in for small lengths MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For small lengths (below 64 bytes) use shorter code paths, this increases performance of function by up to 40%. Signed-off-by: Piotr Dałek --- src/common/buffer.cc | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 7e34a03c29ce..5eccdfe05498 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -946,9 +946,49 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER; assert(_raw); assert(o <= _len); assert(o+l <= _len); + char* dest = _raw->data + _off + o; if (crc_reset) _raw->invalidate_crc(); - memcpy(c_str()+o, src, l); + if (l < 64) { + switch (l) { + case 1: + *((uint8_t*)(dest)) = *((uint8_t*)(src)); + return; + case 2: + *((uint16_t*)(dest)) = *((uint16_t*)(src)); + return; + case 3: + *((uint16_t*)(dest)) = *((uint16_t*)(src)); + *((uint8_t*)(dest+2)) = *((uint8_t*)(src+2)); + return; + case 4: + *((uint32_t*)(dest)) = *((uint32_t*)(src)); + return; + case 8: + *((uint64_t*)(dest)) = *((uint64_t*)(src)); + return; + default: + int cursor = 0; + while (l >= sizeof(uint64_t)) { + *((uint64_t*)(dest + cursor)) = *((uint64_t*)(src + cursor)); + cursor += sizeof(uint64_t); + l -= sizeof(uint64_t); + } + while (l >= sizeof(uint32_t)) { + *((uint32_t*)(dest + cursor)) = *((uint32_t*)(src + cursor)); + cursor += sizeof(uint32_t); + l -= sizeof(uint32_t); + } + while (l > 0) { + *(dest + cursor) = *(src + cursor); + cursor++; + l--; + } + return; + } + } else { + memcpy(dest, src, l); + } } void buffer::ptr::zero(bool crc_reset) -- 2.47.3