Skip to content

Optimize Finder.get_siblings/2 memory usage and speed#663

Merged
philss merged 1 commit intophilss:mainfrom
preciz:perf/optimize-get-siblings
Mar 17, 2026
Merged

Optimize Finder.get_siblings/2 memory usage and speed#663
philss merged 1 commit intophilss:mainfrom
preciz:perf/optimize-get-siblings

Conversation

@preciz
Copy link
Contributor

@preciz preciz commented Mar 17, 2026

Replaced a multi-pass pipeline (Enum.reverse |> Enum.drop_while |> tl |> Enum.filter) with a single-pass tail-recursive approach.

Since children_nodes_ids are stored in reverse document order, iterating over them and prepending to an accumulator naturally reverses the relevant subsequent siblings back into forward document order without needing to iterate the preceding siblings or create intermediate lists.

Benchmark results:

Name                       ips        average  deviation         median         99th %
new_get_siblings         89.90       11.12 ms    ±14.39%       10.97 ms       15.05 ms
old_get_siblings         41.31       24.21 ms    ±10.01%       24.15 ms       31.30 ms

Comparison:
new_get_siblings         89.90
old_get_siblings         41.31 - 2.18x slower +13.09 ms

Memory usage statistics:

Name                Memory usage
new_get_siblings         2.97 MB
old_get_siblings        10.31 MB - 3.47x memory usage +7.34 MB

Replaced a multi-pass pipeline (`Enum.reverse |> Enum.drop_while |> tl |> Enum.filter`) with a single-pass tail-recursive approach.

Since `children_nodes_ids` are stored in reverse document order, iterating over them and prepending to an accumulator naturally reverses the relevant subsequent siblings back into forward document order without needing to iterate the preceding siblings or create intermediate lists.

Benchmark results when calling `get_siblings` on all nodes of a large document:

```
Name                       ips        average  deviation         median         99th %
new_get_siblings         89.90       11.12 ms    ±14.39%       10.97 ms       15.05 ms
old_get_siblings         41.31       24.21 ms    ±10.01%       24.15 ms       31.30 ms

Comparison:
new_get_siblings         89.90
old_get_siblings         41.31 - 2.18x slower +13.09 ms

Memory usage statistics:

Name                Memory usage
new_get_siblings         2.97 MB
old_get_siblings        10.31 MB - 3.47x memory usage +7.34 MB
```
@preciz preciz marked this pull request as ready for review March 17, 2026 10:11
@philss philss merged commit d6f8407 into philss:main Mar 17, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants