Merge pull request #5243 from tomerarazy/master

Cache Long as strings in CommandEncoder in order to reduce allocations and improve performance
pull/5261/merge
Nikita Koksharov 2 years ago committed by GitHub
commit 74d8f741ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -27,7 +27,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/
package org.redisson.client.handler;
@ -44,6 +44,10 @@ import org.redisson.config.CommandMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
/**
* Redis protocol command encoder
*
@ -59,6 +63,21 @@ public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
private static final char BYTES_PREFIX = '$';
private static final byte[] CRLF = "\r\n".getBytes();
private static final Integer LONG_TO_STRING_CACHE_SIZE = 1000;
private static final List<byte[]> LONG_TO_STRING_CACHE = LongStream.range(0, LONG_TO_STRING_CACHE_SIZE)
.mapToObj(Long::toString)
.map(s -> s.getBytes(CharsetUtil.US_ASCII))
.collect(Collectors.toList());
public static byte[] longToString(long number) {
if (number < LONG_TO_STRING_CACHE.size()) {
return LONG_TO_STRING_CACHE.get((int) number);
} else {
return Long.toString(number).getBytes(CharsetUtil.US_ASCII);
}
}
private CommandMapper commandMapper;
public CommandEncoder(CommandMapper commandMapper) {
@ -80,7 +99,7 @@ public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
throw e;
}
}
@Override
protected void encode(ChannelHandlerContext ctx, CommandData<?, ?> msg, ByteBuf out) throws Exception {
try {
@ -89,7 +108,7 @@ public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
if (msg.getCommand().getSubName() != null) {
len++;
}
out.writeCharSequence(Long.toString(len), CharsetUtil.US_ASCII);
out.writeBytes(longToString(len));
out.writeBytes(CRLF);
String name = commandMapper.map(msg.getCommand().getName());
@ -105,7 +124,7 @@ public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
buf.release();
}
}
if (log.isTraceEnabled()) {
String info = out.toString(CharsetUtil.UTF_8);
if (RedisCommands.AUTH.equals(msg.getCommand())) {
@ -138,18 +157,18 @@ public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
ByteBufUtil.writeUtf8(buf, payload);
return buf;
}
private void writeArgument(ByteBuf out, byte[] arg) {
out.writeByte(BYTES_PREFIX);
out.writeCharSequence(Long.toString(arg.length), CharsetUtil.US_ASCII);
out.writeBytes(longToString(arg.length));
out.writeBytes(CRLF);
out.writeBytes(arg);
out.writeBytes(CRLF);
}
private void writeArgument(ByteBuf out, ByteBuf arg) {
out.writeByte(BYTES_PREFIX);
out.writeCharSequence(Long.toString(arg.readableBytes()), CharsetUtil.US_ASCII);
out.writeBytes(longToString(arg.readableBytes()));
out.writeBytes(CRLF);
out.writeBytes(arg, arg.readerIndex(), arg.readableBytes());
out.writeBytes(CRLF);

Loading…
Cancel
Save