acruise commented on issue #6765:
URL: 
https://github.com/apache/datafusion-comet/issues/6765#issuecomment-6582739762

   I implemented this as described: `ArrayWriter`, `StructWriter` and 
`MapWriter` each keep one
   `UnsafeArrayData` / `UnsafeRow` / `UnsafeMapData` and point it at each 
value, and `ArrowWriter`
   collects those views at construction (by type, so each is detached through a 
direct call, not a
   virtual one) and points them at an empty layout after every `write` and in 
`finish`. A flat schema
   collects none. The reachability test passes with the detach and fails 
without it, for unsafe rows
   and for generic rows holding unsafe values, with and without nulls.
   
   The reuse saves what this issue measured, but the per-row detach costs about 
the same, so against
   `main` the net is nil, and `array<map<...>>` loses to the inlining quirk in 
#6757.
   
   Throwaway harness: one column of 8192 unsafe rows per shape, every tenth row 
and element null,
   collections of `i % 6` elements, all ten shapes warmed together in one JVM, 
best of 30 rounds after
   10 warmup rounds, median of three JVMs. Apple M3 Max, assertions off (`-ea` 
removed from the test
   argLine). ns per row:
   
   | shape | main (21) | reuse, no detach (21) | reuse + per-row detach (21) | 
main (17) | reuse, no detach (17) | reuse + per-row detach (17) |
   |---|---|---|---|---|---|---|
   | int | 5.8 | 5.9 | 6.8 | 7.0 | 6.9 | 6.5 |
   | string | 12.2 | 11.4 | 12.6 | 12.2 | 12.0 | 11.8 |
   | array<string> | 28.5 | 25.9 | 29.1 | 30.0 | 27.4 | 27.2 |
   | map<string,string> | 50.3 | 47.8 | 52.4 | 52.7 | 49.1 | 50.5 |
   | array<struct<int,string>> | 55.4 | 53.4 | 57.0 | 58.2 | 53.9 | 55.3 |
   | array<array<int>> | 44.0 | 41.8 | 45.7 | 44.7 | 43.3 | 45.6 |
   | map<int,long> | 29.5 | 27.5 | 30.6 | 29.7 | 27.6 | 31.5 |
   | struct<int,string> | 21.9 | 20.8 | 22.0 | 22.0 | 20.3 | 22.1 |
   | array<map<string,int>> | 97.8 | 111.2 | 112.6 | 99.4 | 94.4 | 121.0 |
   | row of 8 (int, long, string, double, array, map, struct, binary) | 119.6 | 
114.4 | 124.0 | 124.4 | 116.6 | 124.7 |
   
   (21) is JDK 21.0.12, (17) is JDK 17.0.19. Run-to-run spread is about 2 ns on 
the nested shapes.
   
   Reading it:
   
   - Reuse without any detach, which is what #6730 had before 0623dbac51, is 2 
to 4 ns per row faster
     than `main` on the nested shapes and 5 to 8 on the wide row, on both JDKs. 
That matches the table
     in this issue.
   - Detaching once per row gives all of that back. One `pointTo` per nested 
writer per row is 1 to 3
     ns, the same order as the saving, and with four nested writers in the wide 
row it is a wash. On
     JDK 21 every nested shape is at or slightly above `main`; on JDK 17 three 
are 2 to 3 ns under,
     two are 1 to 2 ns over, the rest are equal.
   - `array<map<string,int>>` is 15 to 20% slower with the reuse on both JDKs, 
with or without the
     detach. That is the C2 inlining quirk in #6757, which the view-per-value 
code on `main` happens
     to avoid.
   
   The first point is the only version that pays, and it keeps up to one row 
reachable per nested
   writer until the batch's `finish`, which is what the #6730 review rejected. 
Since a per-row detach
   costs what the reuse saves, the next thing to try is detaching once per 
batch instead: at `finish`
   and `reset`, with the same views. That bounds the retention to one row per 
nested writer for the
   lifetime of one batch, at no per-row cost, and gives the "reuse, no detach" 
column above. I'll
   measure that and the `array<map>` case before opening anything.
   


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