iemejia opened a new issue, #3516:
URL: https://github.com/apache/parquet-java/issues/3516

   ## Background
   
   `DeltaByteArrayWriter.writeBytes(Binary)` is the per-value entry point for 
the `DELTA_BYTE_ARRAY` encoding. For each value it computes the common prefix 
with the previous value and forwards the suffix to a 
`DeltaLengthByteArrayValuesWriter`. The suffix path currently does:
   
   ```java
   suffixWriter.writeBytes(v.slice(i, vb.length - i));
   ```
   
   which:
   
   1. Allocates a `ByteArraySliceBackedBinary` wrapper for the suffix 
(`Binary.slice()`).
   2. Dispatches through `Binary.writeTo(OutputStream)` → `out.write(bytes, 
offset, length)`.
   3. Inside `DeltaLengthByteArrayValuesWriter.writeBytes(Binary)`, the value 
first goes through a `LittleEndianDataOutputStream` wrapper that adds no useful 
work for `byte[]` writes (it only matters for 
`writeInt`/`writeLong`/`writeShort`).
   
   For short strings, the per-value `Binary.slice()` allocation and the wrapper 
indirection dominate the actual work of copying a few bytes.
   
   `DeltaLengthByteArrayValuesWriter` itself wraps its 
`CapacityByteArrayOutputStream` with a `LittleEndianDataOutputStream` that is 
only used for `Binary.writeTo()` — i.e., it adds an extra layer of dispatch on 
every value but never uses any of LE's actual functionality 
(`writeInt`/`writeLong`/etc.).
   
   ## Proposal
   
   Two related changes, both in the delta byte-array write path:
   
   1. **`DeltaLengthByteArrayValuesWriter`**: drop the unused 
`LittleEndianDataOutputStream` wrapper. `Binary.writeTo(arrayOut)` works 
directly with the underlying `CapacityByteArrayOutputStream`. Add a new 
package-private method:
   
      ```java
      public void writeBytes(byte[] data, int offset, int length) {
        lengthWriter.writeInteger(length);
        arrayOut.write(data, offset, length);
      }
      ```
   
      for callers that already have the raw bytes and don't want to allocate a 
`Binary` wrapper.
   
   2. **`DeltaByteArrayWriter`**: tighten the `suffixWriter` field type to 
`DeltaLengthByteArrayValuesWriter` (it's always constructed as one) so the new 
`writeBytes(byte[], int, int)` overload is callable. Replace the suffix call 
with the raw-bytes overload:
   
      ```java
      suffixWriter.writeBytes(vb, i, vb.length - i);
      ```
   
      eliminating the per-value `Binary.slice()` allocation.
   
   ## Expected impact
   
   From local benchmarks (`BinaryEncodingBenchmark.encodeDeltaByteArray`, 
`BinaryEncodingBenchmark.encodeDeltaLengthByteArray` — being added in #3512):
   
   - `encodeDeltaByteArray` (short strings, low cardinality): **+23% to +33%**
   - `encodeDeltaLengthByteArray` (short strings, low cardinality): **+16% to 
+18%**
   - Long-string cases: flat (the per-value alloc is amortized away)
   
   ## Files affected
   
   - 
`parquet-column/src/main/java/org/apache/parquet/column/values/deltastrings/DeltaByteArrayWriter.java`
   - 
`parquet-column/src/main/java/org/apache/parquet/column/values/deltalengthbytearray/DeltaLengthByteArrayValuesWriter.java`
   
   No public API change. No file format change.


-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to