From 87f99381ae2a5d06511ab11f333a0a4e9474c82f Mon Sep 17 00:00:00 2001 From: Jungtaek Lim Date: Thu, 18 Sep 2014 09:33:10 +0900 Subject: [PATCH] Optimize CRC16 calculation (with optimization of slot decision) --- .../java/redis/clients/util/JedisClusterCRC16.java | 12 +++++++----- .../jedis/tests/benchmark/CRC16Benchmark.java | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/redis/clients/util/JedisClusterCRC16.java b/src/main/java/redis/clients/util/JedisClusterCRC16.java index 45d831e249..65ddacb1a7 100644 --- a/src/main/java/redis/clients/util/JedisClusterCRC16.java +++ b/src/main/java/redis/clients/util/JedisClusterCRC16.java @@ -4,7 +4,7 @@ * CRC16 Implementation according to CCITT standard * Polynomial : 1021 (x^16 + x^12 + x^5 + 1) * - * @see: http://redis.io/topics/cluster-spec + * @see http://redis.io/topics/cluster-spec * Appendix A. CRC16 reference implementation in ANSI C */ public class JedisClusterCRC16 { @@ -36,22 +36,24 @@ public static int getSlot(String key) { key = key.substring(s+1, e); } } - return getCRC16(key) % 16384; + // optimization with modulo operator with power of 2 + // equivalent to getCRC16(key) % 16384 + return getCRC16(key) & (16384 - 1); } /** * Create a CRC16 checksum from the bytes. - * implementation is from mp911de/lettuce + * implementation is from mp911de/lettuce, modified with some more optimizations * - * @author Mark Paluch * @param bytes * @return CRC16 as integer value + * @see https://github.com/xetorthio/jedis/pull/733#issuecomment-55840331 */ public static int getCRC16(byte[] bytes) { int crc = 0x0000; for (byte b : bytes) { - crc = ((crc << 8) ^ LOOKUP_TABLE[((crc >> 8) ^ (b & 0xFF)) & 0xFF]) & 0xFFFF; + crc = ((crc << 8) ^ LOOKUP_TABLE[((crc >>> 8) ^ (b & 0xFF)) & 0xFF]); } return crc & 0xFFFF; } diff --git a/src/test/java/redis/clients/jedis/tests/benchmark/CRC16Benchmark.java b/src/test/java/redis/clients/jedis/tests/benchmark/CRC16Benchmark.java index 2b78ae8be8..b46fea9ec5 100644 --- a/src/test/java/redis/clients/jedis/tests/benchmark/CRC16Benchmark.java +++ b/src/test/java/redis/clients/jedis/tests/benchmark/CRC16Benchmark.java @@ -5,13 +5,13 @@ import redis.clients.util.JedisClusterCRC16; public class CRC16Benchmark { - private static final int TOTAL_OPERATIONS = 10000000; + private static final int TOTAL_OPERATIONS = 100000000; private static String[] TEST_SET = { "", "123456789", "sfger132515", "hae9Napahngaikeethievubaibogiech", "AAAAAAAAAAAAAAAAAAAAAA", "Hello, World!" }; - + public static void main(String[] args) { long begin = Calendar.getInstance().getTimeInMillis(); @@ -23,5 +23,5 @@ public static void main(String[] args) { System.out.println(((1000 * TOTAL_OPERATIONS) / elapsed) + " ops"); } - + } \ No newline at end of file