Commit ceaa829
authored
Sort nodeset on demand (#330)
Delay sorting, only sort when it is needed.
In most case, sorting nodeset is not needed. Sort is only required in:
- Final result
- Creating nodesets(each nodeset should be axis-ordered) from a single
nodeset
- Ideally, this can be skipped if the following predicate is not
position-dependent
- Nodeset passed to a function (first node in document order is used)
### Number of sort operations
| XPath | master(before #315) | master(after #315) | this PR |
| --- | --- | --- | --- |
| `/a/b/c/d/e` | 3 | 4 | 1 |
| `(a/b/c/d)[position()>1]/e/f/g` | 5 | 7 | 2 |
| `number(/a/b/c/d/e)` | 3 | 4 |1 |
| `count(/a/b/c/d/e)` | 3 | 4 | 0 |
| `//a//b//c//d//e` | 8 | 9 | 1 |
| `/a[1]/b[1]/c[1]/d[1]/e` | 0 | 1 | 1 |
#315 removed one `nodesets.size == 1` optimization path. This pull
request will reduce the performance regression.
To reduce more sort calls, we need to mark nodeset ordering: introducing
`Nodeset = Struct.new(:nodes, :order)`
but IMO, it shouldn't be done now. If `sort` is optimized, one extra
sort won't be a problem. Optimizing `step` will be harder and the code
may be complicated.
### Note
This pull request will slightly add complexity and a risk to forgot
sorting the nodeset in some path.
The effect may seem drastic in some case for now, but it's just because
`sort` is currently worst `O(n^2)`. We can improve `sort` performance,
so there's an option to leave the sort strategy simple.1 parent 9640216 commit ceaa829
4 files changed
Lines changed: 31 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
88 | | - | |
| 88 | + | |
89 | 89 | | |
90 | | - | |
| 90 | + | |
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
| |||
149 | 149 | | |
150 | 150 | | |
151 | 151 | | |
152 | | - | |
| 152 | + | |
153 | 153 | | |
154 | 154 | | |
155 | 155 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
159 | | - | |
| 159 | + | |
160 | 160 | | |
161 | 161 | | |
162 | 162 | | |
| |||
323 | 323 | | |
324 | 324 | | |
325 | 325 | | |
326 | | - | |
| 326 | + | |
327 | 327 | | |
328 | 328 | | |
329 | 329 | | |
| |||
571 | 571 | | |
572 | 572 | | |
573 | 573 | | |
| 574 | + | |
574 | 575 | | |
575 | 576 | | |
576 | 577 | | |
| |||
621 | 622 | | |
622 | 623 | | |
623 | 624 | | |
624 | | - | |
| 625 | + | |
625 | 626 | | |
626 | 627 | | |
627 | 628 | | |
| |||
761 | 762 | | |
762 | 763 | | |
763 | 764 | | |
764 | | - | |
| 765 | + | |
765 | 766 | | |
766 | 767 | | |
767 | 768 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
87 | 87 | | |
88 | 88 | | |
89 | 89 | | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
90 | 97 | | |
91 | 98 | | |
92 | 99 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1505 | 1505 | | |
1506 | 1506 | | |
1507 | 1507 | | |
| 1508 | + | |
| 1509 | + | |
| 1510 | + | |
| 1511 | + | |
| 1512 | + | |
| 1513 | + | |
| 1514 | + | |
| 1515 | + | |
| 1516 | + | |
| 1517 | + | |
| 1518 | + | |
| 1519 | + | |
| 1520 | + | |
| 1521 | + | |
| 1522 | + | |
| 1523 | + | |
1508 | 1524 | | |
1509 | 1525 | | |
0 commit comments