Skip to content

Optimize FlatText.get/3 memory usage and speed#664

Merged
philss merged 3 commits intophilss:mainfrom
preciz:perf/optimize-flat-text
Mar 17, 2026
Merged

Optimize FlatText.get/3 memory usage and speed#664
philss merged 3 commits intophilss:mainfrom
preciz:perf/optimize-flat-text

Conversation

@preciz
Copy link
Contributor

@preciz preciz commented Mar 17, 2026

Optimizes shallow text extraction in Floki.FlatText by replacing Enum.reduce/3 with a direct tail-recursive approach.

Performance Impact:
Across various Benchee tests (Small/Medium/Large HTML, and highly nested lists), this approach yields:

  • ~10% to 25% faster execution speeds.
  • ~35% to 45% reduction in memory allocations.

Tests:
Adds a comprehensive set of edge-case tests to flat_text_test.exs (covering deeply nested nodes, mixed tuples, and sequential text) to guarantee 100% behavioral parity with the previous implementation and protect against regressions.

preciz added 3 commits March 17, 2026 11:21
Replaced Enum.reduce/3 with an optimal tail-recursive approach in FlatText.

By traversing lists manually, we avoid the overhead of the Enumerable protocol and the allocation of anonymous closures per reduction iteration.

Benchmark results when running Floki.FlatText.get on a large document:

```text
Name                     ips        average  deviation         median         99th %
Tail recursion        3.21 M      311.16 ns ±23057.88%          50 ns         160 ns
Enum.reduce           2.76 M      361.71 ns ±20499.20%          50 ns         180 ns

Comparison:
Tail recursion        3.21 M
Enum.reduce           2.76 M - 1.16x slower +50.55 ns

Memory usage statistics:

Name              Memory usage
Tail recursion           136 B
Enum.reduce              208 B - 1.53x memory usage +72 B
```
@philss philss merged commit f50d7f2 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