[
https://issues.apache.org/jira/browse/FLINK-39044?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Natea Eshetu Beshada updated FLINK-39044:
-----------------------------------------
Description:
Summary
BinaryStringData.copy() currently always allocates a new BinaryStringData
object and copies the underlying byte array, even when the source is already
immutable and can be safely shared. This is unnecessary
overhead for strings that occupy a single memory segment at offset 0 with no
wasted space.
Proposed Change
Return this from BinaryStringData.copy() when all of the following conditions
are met:
- The string occupies exactly one MemorySegment
- The offset is 0
- The segment size equals the string's byte length (no wasted space)
This is safe because BinaryStringData is immutable once constructed - none of
its public methods mutate the underlying data.
Benchmark Results
{{
┌──────────────────────────┬───────────────────┬────────────────────┬─────────────┐}}
{{ │ Benchmark │ Baseline (ops/ms) │ Optimized (ops/ms) │
Improvement │}}
{{
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
{{ │ copyCompactString │ 18,381 ± 22,770 │ 807,198 ± 13,825 │
+4,292% │}}
{{
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
{{ │ copyLargeString │ 3,551 ± 4,718 │ 748,334 ± 6,211 │
+20,975% │}}
{{
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
{{ │ deserializeCompactString │ 60,560 ± 34,536 │ 98,886 ± 1,043 │ +63%
│}}
{{
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
{{ │ deserializeLargeString │ 19,253 ± 181 │ 33,917 ± 136 │ +76%
│}}
{{
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
{{ │ serializeCompactString │ 125,307 ± 2,451 │ 122,648 ± 968 │ -2%
(noise) │}}
{{
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
{{ │ serializeLargeString │ 27,746 ± 3,046 │ 27,646 ± 2,968 │ 0%
(noise) │}}
{{
└──────────────────────────┴───────────────────┴────────────────────┴─────────────┘}}
{{ JMH config: 2 forks, 5 warmup iterations, 5 measurement iterations}}
{{ Baseline: origin/master @ 7488449d086}}
Note: The baseline copy benchmarks had high variance due to GC pressure from
allocation. The optimized version eliminates allocation entirely, resulting in
very low variance
was:
Summary
BinaryStringData.copy() currently always allocates a new BinaryStringData
object and copies the underlying byte array, even when the source is already
immutable and can be safely shared. This is unnecessary
overhead for strings that occupy a single memory segment at offset 0 with no
wasted space.
Proposed Change
Return this from BinaryStringData.copy() when all of the following conditions
are met:
- The string occupies exactly one MemorySegment
- The offset is 0
- The segment size equals the string's byte length (no wasted space)
This is safe because BinaryStringData is immutable once constructed - none of
its public methods mutate the underlying data.
Benchmark Results
┌──────────────────────────┬───────────────────┬────────────────────┬─────────────┐
│ Benchmark │ Baseline (ops/ms) │ Optimized (ops/ms) │
Improvement │
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤
│ copyCompactString │ 18,381 ± 22,770 │ 807,198 ± 13,825 │ +4,292%
│
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤
│ copyLargeString │ 3,551 ± 4,718 │ 748,334 ± 6,211 │
+20,975% │
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤
│ deserializeCompactString │ 60,560 ± 34,536 │ 98,886 ± 1,043 │ +63%
│
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤
│ deserializeLargeString │ 19,253 ± 181 │ 33,917 ± 136 │ +76%
│
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤
│ serializeCompactString │ 125,307 ± 2,451 │ 122,648 ± 968 │ -2%
(noise) │
├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤
│ serializeLargeString │ 27,746 ± 3,046 │ 27,646 ± 2,968 │ 0%
(noise) │
└──────────────────────────┴───────────────────┴────────────────────┴─────────────┘
JMH config: 2 forks, 5 warmup iterations, 5 measurement iterations
Baseline: origin/master @ 7488449d086
Note: The baseline copy benchmarks had high variance due to GC pressure from
allocation. The optimized version eliminates allocation entirely, resulting in
near-zero variance
> Optimize BinaryStringData.copy() to return this for immutable strings
> ---------------------------------------------------------------------
>
> Key: FLINK-39044
> URL: https://issues.apache.org/jira/browse/FLINK-39044
> Project: Flink
> Issue Type: Improvement
> Components: Table SQL / Runtime
> Reporter: Natea Eshetu Beshada
> Priority: Major
>
> Summary
> BinaryStringData.copy() currently always allocates a new BinaryStringData
> object and copies the underlying byte array, even when the source is already
> immutable and can be safely shared. This is unnecessary
> overhead for strings that occupy a single memory segment at offset 0 with
> no wasted space.
> Proposed Change
> Return this from BinaryStringData.copy() when all of the following
> conditions are met:
> - The string occupies exactly one MemorySegment
> - The offset is 0
> - The segment size equals the string's byte length (no wasted space)
> This is safe because BinaryStringData is immutable once constructed - none
> of its public methods mutate the underlying data.
> Benchmark Results
> {{
> ┌──────────────────────────┬───────────────────┬────────────────────┬─────────────┐}}
> {{ │ Benchmark │ Baseline (ops/ms) │ Optimized (ops/ms) │
> Improvement │}}
> {{
> ├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
> {{ │ copyCompactString │ 18,381 ± 22,770 │ 807,198 ± 13,825 │
> +4,292% │}}
> {{
> ├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
> {{ │ copyLargeString │ 3,551 ± 4,718 │ 748,334 ± 6,211 │
> +20,975% │}}
> {{
> ├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
> {{ │ deserializeCompactString │ 60,560 ± 34,536 │ 98,886 ± 1,043 │
> +63% │}}
> {{
> ├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
> {{ │ deserializeLargeString │ 19,253 ± 181 │ 33,917 ± 136 │
> +76% │}}
> {{
> ├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
> {{ │ serializeCompactString │ 125,307 ± 2,451 │ 122,648 ± 968 │ -2%
> (noise) │}}
> {{
> ├──────────────────────────┼───────────────────┼────────────────────┼─────────────┤}}
> {{ │ serializeLargeString │ 27,746 ± 3,046 │ 27,646 ± 2,968 │ 0%
> (noise) │}}
> {{
> └──────────────────────────┴───────────────────┴────────────────────┴─────────────┘}}
> {{ JMH config: 2 forks, 5 warmup iterations, 5 measurement iterations}}
> {{ Baseline: origin/master @ 7488449d086}}
> Note: The baseline copy benchmarks had high variance due to GC pressure from
> allocation. The optimized version eliminates allocation entirely, resulting
> in very low variance
--
This message was sent by Atlassian Jira
(v8.20.10#820010)