From 235f655cab0f13dc4f310852f52685530b7b2ef9 Mon Sep 17 00:00:00 2001 From: Muhammad Zahalqa Date: Sat, 13 Jun 2020 11:43:02 +0300 Subject: [PATCH] Optimize rdbEncodeInteger using bit operations use sign extension mov instructions into 8/16/32 bits int registers to check if value fits into 8/16/32 bit width. ``` int function(long long value){ struct SignExtendBits{ long long bits8: 8; long long bits16: 16; long long bits32: 32; } v; v.bits8 = value; if ( v.bits8 == value ) return 1; m.bits16 = value; if ( m.bits16 == value ) return 2; m.bits32 = value; if ( m.bits32 == value ) return 3; return 0; } Compiles to compact code even with -O1 : function(long long): movsx rcx, dil mov eax, 1 cmp rcx, rdi je .LBB1_3 movsx rcx, di mov eax, 2 cmp rcx, rdi je .LBB1_3 movsxd rcx, edi xor eax, eax cmp rcx, rdi sete al shl eax, 2 .LBB1_3: ret ``` --- src/rdb.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/rdb.cpp b/src/rdb.cpp index ea82cdbd8..a4034b549 100644 --- a/src/rdb.cpp +++ b/src/rdb.cpp @@ -239,25 +239,38 @@ uint64_t rdbLoadLen(rio *rdb, int *isencoded) { * representation is stored in the buffer pointer to by "enc" and the string * length is returned. Otherwise 0 is returned. */ int rdbEncodeInteger(long long value, unsigned char *enc) { - if (value >= -(1<<7) && value <= (1<<7)-1) { + struct SignExtendBits{ + long long bits8: 8; + long long bits16: 16; + long long bits32: 32; + } v; + + v.bits8 = value; + if (v.bits8 == value) { enc[0] = (RDB_ENCVAL<<6)|RDB_ENC_INT8; - enc[1] = value&0xFF; + enc[1] = v.bits8; return 2; - } else if (value >= -(1<<15) && value <= (1<<15)-1) { + } + + v.bits16 = value; + if (v.bits16 == value) { enc[0] = (RDB_ENCVAL<<6)|RDB_ENC_INT16; enc[1] = value&0xFF; enc[2] = (value>>8)&0xFF; return 3; - } else if (value >= -((long long)1<<31) && value <= ((long long)1<<31)-1) { + } + + v.bits32 = value; + if (v.bits32 == value) { enc[0] = (RDB_ENCVAL<<6)|RDB_ENC_INT32; enc[1] = value&0xFF; enc[2] = (value>>8)&0xFF; enc[3] = (value>>16)&0xFF; enc[4] = (value>>24)&0xFF; return 5; - } else { - return 0; } + + return 0; } /* Loads an integer-encoded object with the specified encoding type "enctype".