Skip to content

Commit 55387d1

Browse files
authored
perf: write numbers directly to the stream (#4229)
Write number values (long, int, float, double) directly to the underlying data stream, instead of first converting them to a byte array. This saves a bit of memory allocation for every write, which again reduces GC pressure.
1 parent d3357c3 commit 55387d1

File tree

4 files changed

+20
-9
lines changed

4 files changed

+20
-9
lines changed

src/main/java/com/google/cloud/spanner/pgadapter/parsers/DoubleParser.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import com.google.cloud.spanner.pgadapter.error.PGExceptionFactory;
2424
import com.google.cloud.spanner.pgadapter.error.SQLState;
2525
import com.google.common.collect.ImmutableMap;
26+
import java.io.DataOutputStream;
27+
import java.io.IOException;
2628
import java.nio.charset.StandardCharsets;
2729
import javax.annotation.Nonnull;
2830
import org.postgresql.util.ByteConverter;
@@ -88,13 +90,17 @@ static byte[] convertToPG(double value) {
8890
return result;
8991
}
9092

91-
public static byte[] convertToPG(ResultSet resultSet, int position, DataFormat format) {
93+
public static byte[] convertToPG(
94+
DataOutputStream outputStream, ResultSet resultSet, int position, DataFormat format)
95+
throws IOException {
9296
switch (format) {
9397
case SPANNER:
9498
case POSTGRESQL_TEXT:
9599
return Double.toString(resultSet.getDouble(position)).getBytes(StandardCharsets.UTF_8);
96100
case POSTGRESQL_BINARY:
97-
return convertToPG(resultSet.getDouble(position));
101+
outputStream.writeInt(8);
102+
outputStream.writeDouble(resultSet.getDouble(position));
103+
return null;
98104
default:
99105
throw new IllegalArgumentException("unknown data format: " + format);
100106
}

src/main/java/com/google/cloud/spanner/pgadapter/parsers/FloatParser.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import com.google.cloud.spanner.pgadapter.error.PGExceptionFactory;
2323
import com.google.cloud.spanner.pgadapter.error.SQLState;
2424
import com.google.common.collect.ImmutableMap;
25+
import java.io.DataOutputStream;
26+
import java.io.IOException;
2527
import java.nio.charset.StandardCharsets;
2628
import javax.annotation.Nonnull;
2729
import org.postgresql.util.ByteConverter;
@@ -85,13 +87,17 @@ static byte[] convertToPG(float value) {
8587
return result;
8688
}
8789

88-
public static byte[] convertToPG(ResultSet resultSet, int position, DataFormat format) {
90+
public static byte[] convertToPG(
91+
DataOutputStream outputStream, ResultSet resultSet, int position, DataFormat format)
92+
throws IOException {
8993
switch (format) {
9094
case SPANNER:
9195
case POSTGRESQL_TEXT:
9296
return Float.toString(resultSet.getFloat(position)).getBytes(StandardCharsets.UTF_8);
9397
case POSTGRESQL_BINARY:
94-
return convertToPG(resultSet.getFloat(position));
98+
outputStream.writeInt(4);
99+
outputStream.writeFloat(resultSet.getFloat(position));
100+
return null;
95101
default:
96102
throw new IllegalArgumentException("unknown data format: " + format);
97103
}

src/main/java/com/google/cloud/spanner/pgadapter/parsers/LongParser.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,8 @@ static void writeToPG(
125125
StringParser.writeToPG(sessionState, outputStream, getLongAsString(resultSet, position));
126126
break;
127127
case POSTGRESQL_BINARY:
128-
byte[] value = convertToPG(resultSet.getLong(position));
129-
outputStream.writeInt(value.length);
130-
outputStream.write(value);
128+
outputStream.writeInt(8);
129+
outputStream.writeLong(resultSet.getLong(position));
131130
break;
132131
default:
133132
throw new IllegalArgumentException("unknown data format: " + format);

src/main/java/com/google/cloud/spanner/pgadapter/utils/Converter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,9 @@ public static byte[] convertToPG(
169169
case DATE:
170170
return DateParser.convertToPG(sessionState, outputStream, result, position, format);
171171
case FLOAT32:
172-
return FloatParser.convertToPG(result, position, format);
172+
return FloatParser.convertToPG(outputStream, result, position, format);
173173
case FLOAT64:
174-
return DoubleParser.convertToPG(result, position, format);
174+
return DoubleParser.convertToPG(outputStream, result, position, format);
175175
case INT64:
176176
case PG_OID:
177177
return LongParser.convertToPG(sessionState, outputStream, result, position, format);

0 commit comments

Comments
 (0)