jasonk000 commented on a change in pull request #11721: URL: https://github.com/apache/kafka/pull/11721#discussion_r799082813
########## File path: clients/src/main/java/org/apache/kafka/common/utils/ByteUtils.java ########## @@ -386,18 +386,39 @@ public static void writeDouble(double value, ByteBuffer buffer) { buffer.putDouble(value); } + final static int[] LEADING_ZEROS_TO_U_VARINT_SIZE = new int[] { + // 32 bits, and each 7-bits adds one byte to the output + 5, 5, 5, 5, // 32 + 4, 4, 4, 4, 4, 4, 4, // 28 + 3, 3, 3, 3, 3, 3, 3, // 21 + 2, 2, 2, 2, 2, 2, 2, // 14 + 1, 1, 1, 1, 1, 1, 1, // 7 + 1 // 0 + }; + + final static int[] LEADING_ZEROS_TO_U_VARLONG_SIZE = new int[] { + // 64 bits, and each 7-bits adds one byte to the output + 10, // 64 + 9, 9, 9, 9, 9, 9, 9, // 63 + 8, 8, 8, 8, 8, 8, 8, // 56 + 7, 7, 7, 7, 7, 7, 7, // 49 + 6, 6, 6, 6, 6, 6, 6, // 42 + 5, 5, 5, 5, 5, 5, 5, // 35 + 4, 4, 4, 4, 4, 4, 4, // 28 + 3, 3, 3, 3, 3, 3, 3, // 21 + 2, 2, 2, 2, 2, 2, 2, // 14 + 1, 1, 1, 1, 1, 1, 1, // 7 + 1 // 0 + }; + /** * Number of bytes needed to encode an integer in unsigned variable-length format. * * @param value The signed value */ public static int sizeOfUnsignedVarint(int value) { - int bytes = 1; - while ((value & 0xffffff80) != 0L) { - bytes += 1; - value >>>= 7; - } - return bytes; + int leadingZeros = Integer.numberOfLeadingZeros(value); + return LEADING_ZEROS_TO_U_VARINT_SIZE[leadingZeros]; Review comment: OK, got it. Thank you for the nudges. They are now effectively identical in performance, and the math-version uses 1 less cmp/mov (for array bounds & fetch), with one extra instruction, and no requirement to hit the cache. ``` Benchmark Mode Cnt Score Error Units ByteUtilsBenchmark.testSizeOfUnsignedVarint thrpt 20 503633.665 ± 5214.083 ops/ms ByteUtilsBenchmark.testSizeOfUnsignedVarint:IPC thrpt 2 4.608 insns/clk ByteUtilsBenchmark.testSizeOfUnsignedVarint:L1-dcache-loads thrpt 2 13.002 #/op ByteUtilsBenchmark.testSizeOfUnsignedVarint:branches thrpt 2 5.005 #/op ByteUtilsBenchmark.testSizeOfUnsignedVarint:instructions thrpt 2 31.080 #/op ByteUtilsBenchmark.testSizeOfUnsignedVarintMath thrpt 20 507438.241 ± 5268.695 ops/ms ByteUtilsBenchmark.testSizeOfUnsignedVarintMath:IPC thrpt 2 4.789 insns/clk ByteUtilsBenchmark.testSizeOfUnsignedVarintMath:L1-dcache-loads thrpt 2 11.992 #/op ByteUtilsBenchmark.testSizeOfUnsignedVarintMath:branches thrpt 2 4.004 #/op ByteUtilsBenchmark.testSizeOfUnsignedVarintMath:instructions thrpt 2 32.059 #/op ByteUtilsBenchmark.testSizeOfUnsignedVarintOriginal thrpt 20 371946.626 ± 3105.947 ops/ms ByteUtilsBenchmark.testSizeOfUnsignedVarintOriginal:IPC thrpt 2 5.360 insns/clk ByteUtilsBenchmark.testSizeOfUnsignedVarintOriginal:L1-dcache-loads thrpt 2 14.002 #/op ByteUtilsBenchmark.testSizeOfUnsignedVarintOriginal:branches thrpt 2 7.992 #/op ByteUtilsBenchmark.testSizeOfUnsignedVarintOriginal:instructions thrpt 2 48.931 #/op ``` I'll switch the code over. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: jira-unsubscr...@kafka.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org