[ 
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)

Reply via email to