Обычно есть два подхода. Первый - собрать всё дерево документа целиком. Так делают Wadler-style pretty printers. Это выразительно, но в Rust быстро упирается в память, аллокации и указатели. Второй - стримить вывод по кускам. Так работает Oppen-style подход. Он легче по памяти, но часто принимает локально хорошие решения и не всегда находит глобально лучший layout. Автор предлагает третий вариант: не хранить документ как рекурсивный enum, а описывать его через trait Doc. То есть Text, Concat, Group, Nest и другие элементы становятся отдельными типами, которые умеют сами себя рендерить через layout(). Звучит как мелкая архитектурная правка, но эффект большой: меньше лишних аллокаций, меньше прыжков по памяти, гибче управление Box, Rc и другими стратегиями хранения. В proof-of-concept реализации pye автор получил до 60x ускорения по сравнению с прямой Rust-реализацией алгоритма из paper “A Pretty Expressive Printer”. А в обновлённых тестах вариант с таким дизайном и greedy-алгоритм
👣 В Rust нашли интересный способ ускорить pretty printer - штуку, которая красиво форматирует код, JSON, Lisp и другие структуры
ВчераВчера
5
1 мин