GitHub user arne-bdt edited a comment on the discussion: Why is Quad not a 
composition of the graph Node + Triple?

Thank you for the question — it drove me into a deep analysis.

**Summary:** the optimization would only help where the *access shape differs 
from the storage shape*, and even then it's small — ~24 B per reconstructed 
`Triple` on insert, ~32 B per `Quad` on find. On hot internal scans the JIT 
(escape analysis) often removes even that. The real cost turned out to be heavy 
per-row `find` implementations (including a double-wrapping bug of my own), not 
the `Quad`/`Triple` model itself. 
--> **So I'll close this.**.

**Background**
I tend to use triple stores (e.g. `DatasetGraphMapLink`) rather than quad 
stores, since I typically dont't have more than one or two dozen graphs in one 
dataset and each graph has its own source and update frequency.
With the current `DatasetGraph#add` overloads every triple is reconstructed on 
insert (~24 B; the existing `Triple` can't be reused), and #find/#stream pay 
~32 B per `Quad` on every query over a triple store. Not ideal, but small.

**My mistake:** digging through the implementations I saw conversions 
everywhere and wondered what they cost. I'd just seen a performance gap in my 
MVCC `Graph` vs `DatasetGraph` benchmarks and assumed the quad facade was to 
blame. It wasn't: my `getDefaultGraph()` double-wrapped via 
`GraphView.createDefaultGraph`, so every find went `triple → quad → triple` (a 
measured 56 B = one `Quad` + one `Triple` per row).

**Measured** (JMH + GCProfiler, 6.75 M triples, `consume` = each result escapes 
via a `Blackhole`; under a drop-the-row scan escape analysis takes these to 
~0): — cost + time

| path | DatasetGraphInMemory | DatasetGraphMapLink | COW | MVCC |
|---|--:|--:|--:|--:|
| default — find all triples | 509 B / 1.31 s | 3.9 B / 0.062 s | 56 B / 0.087 
s | 56 B / 0.121 s |
| named — find all triples | 493 B / 1.26 s | 3.9 B / 0.076 s | 24 B / 0.067 s 
| 24 B / 0.075 s |
| named — find all quads | 469 B / 1.51 s |  36 B / 0.147 s | 32 B / 0.068 s | 
32 B / 0.101 s |
| default — contains each triple   | 672 B / 1.77 s |  ~0 B / 0.43 s | 48 B / 
0.80 s | 48 B / 1.83 s |

`DatasetGraphInMemory`'s `Stream`-based `find` allocates a lot per row. 
`DatasetGraphMapLink` is near-zero on the triple API.
COW and MVCC match each other in the resuts but should be as low as 
`DatasetGraphMapLink` --> a todo for me
So the 32 B/row that's negligible next to `DatasetGraphInMemory` is the 
*dominant* read cost for my lean stores — which is where I'll focus, rather 
than on the `Quad`/`Triple` model.

GitHub link: 
https://github.com/apache/jena/discussions/3967#discussioncomment-17171170

----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: [email protected]


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

Reply via email to