From 8a82c183b10cc8e9a7fe6ca279c1d85b77434193 Mon Sep 17 00:00:00 2001 From: Steven van Rossum Date: Tue, 2 Dec 2025 11:52:09 +0000 Subject: [PATCH 1/3] Replace VarInt.getLength with Protobuf's branchless implementation --- .../java/org/apache/beam/sdk/util/VarInt.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java index 5432383f5ad4..ced3c0f1efbc 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java @@ -136,16 +136,19 @@ public static long decodeLong(InputStream stream) throws IOException { /** Returns the length of the encoding of the given value (in bytes). */ public static int getLength(int v) { - return getLength(convertIntToLongNoSignExtend(v)); + // log2(v) / 7 + 1 rewritten as multiplication by 9/64 instead of a division by 7. + // Log2 is performed using a bit counting instruction. + // Multiplication by 9 is performed using a 3-bit left shift and add. + // Division by 64 is performed using a 6-bit right shift. + return ((Integer.SIZE * 9 + (1 << 6)) - (Integer.numberOfLeadingZeros(v) * 9)) >>> 6; } /** Returns the length of the encoding of the given value (in bytes). */ public static int getLength(long v) { - int result = 0; - do { - result++; - v >>>= 7; - } while (v != 0); - return result; + // log2(v) / 7 + 1 rewritten as multiplication by 9/64 instead of a division by 7. + // Log2 is performed using a bit counting instruction. + // Multiplication by 9 is performed using a 3-bit left shift and add. + // Division by 64 is performed using a 6-bit right shift. + return ((Long.SIZE * 9 + (1 << 6)) - (Long.numberOfLeadingZeros(v) * 9)) >>> 6; } } From 07b1ee1159c351ee19507196a20cec4a035ec84f Mon Sep 17 00:00:00 2001 From: Steven van Rossum Date: Tue, 2 Dec 2025 14:28:31 +0000 Subject: [PATCH 2/3] Use CodedOutputStream's computeUInt32SizeNoTag and computeUInt64SizeNoTag --- .../main/java/org/apache/beam/sdk/util/VarInt.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java index ced3c0f1efbc..02ac2586d814 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import com.google.protobuf.CodedOutputStream; /** * Variable-length encoding for integers. @@ -136,19 +137,11 @@ public static long decodeLong(InputStream stream) throws IOException { /** Returns the length of the encoding of the given value (in bytes). */ public static int getLength(int v) { - // log2(v) / 7 + 1 rewritten as multiplication by 9/64 instead of a division by 7. - // Log2 is performed using a bit counting instruction. - // Multiplication by 9 is performed using a 3-bit left shift and add. - // Division by 64 is performed using a 6-bit right shift. - return ((Integer.SIZE * 9 + (1 << 6)) - (Integer.numberOfLeadingZeros(v) * 9)) >>> 6; + return CodedOutputStream.computeUInt32SizeNoTag(v); } /** Returns the length of the encoding of the given value (in bytes). */ public static int getLength(long v) { - // log2(v) / 7 + 1 rewritten as multiplication by 9/64 instead of a division by 7. - // Log2 is performed using a bit counting instruction. - // Multiplication by 9 is performed using a 3-bit left shift and add. - // Division by 64 is performed using a 6-bit right shift. - return ((Long.SIZE * 9 + (1 << 6)) - (Long.numberOfLeadingZeros(v) * 9)) >>> 6; + return CodedOutputStream.computeUInt64SizeNoTag(v); } } From f859813c8065879068f4b3425e19a3b51f5b0696 Mon Sep 17 00:00:00 2001 From: Steven van Rossum Date: Wed, 3 Dec 2025 11:33:34 +0000 Subject: [PATCH 3/3] Run spotless --- .../core/src/main/java/org/apache/beam/sdk/util/VarInt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java index 02ac2586d814..39719d772957 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/VarInt.java @@ -17,11 +17,11 @@ */ package org.apache.beam.sdk.util; +import com.google.protobuf.CodedOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import com.google.protobuf.CodedOutputStream; /** * Variable-length encoding for integers.