BorrowedBuf, ночная функция Rust для оптимизации работы с буферами в I/O-операциях, подверглась критике за сложность использования, проблемы совместимости и ограниченную универсальность
BorrowedBuf — это ночная функция Rust, созданная для оптимизации работы с буферами в операциях ввода-вывода (I/O).
Она позволяет работать с неинициализированной памятью и отслеживает, какая её часть уже использована.
Это должно решать проблему избыточной инициализации, как в примере ниже, где буфер заполняется нулями при каждой итерации, несмотря на то, что read перезаписывает данные:
fn slow_copy( mut rd: impl std::io::Read, mut wr: impl std::io::Write, ) -> std::io::Result<()> { loop { let mut buf = [0; 4096]; let read = rd.read(&mut buf)?; if read == 0 { break Ok(()); } wr.write_all(&buf[..read])?; } }
Проблемы BorrowedBuf
Однако BorrowedBuf вызывает множество нареканий. Основные из них:
- Совместимость с существующим кодом: BorrowedBuf требует поддержки со стороны API, таких как
read_buf
. Если её нет, Rust будет заполнять буфер нулями, сводя на нет всю оптимизацию. Это вызывает проблемы с библиотеками, которые не обновлялись или больше не поддерживаются, напримерhex
илиbase64
. - Отсутствие универсальности: функция работает только с
u8
. Это ограничивает его использование в библиотеках, таких какrand
, которые оперируют разными типами данных. - Сложность использования: BorrowedBuf требует глубокого понимания, чтобы избежать ошибок. Например, неправильное использование может привести к тому, что буфер всё равно будет инициализироваться, несмотря на видимую оптимизацию.
- Логическая путаница: Модель BorrowedBuf разделяет память на инициализированные и неинициализированные части, что делает её сложной для понимания. Аналогия с
Vec
могла бы сделать API более интуитивным.
Возможные альтернативы
Идеальная альтернатива BorrowedBuf пока не найдена. Одно из предложений — замораживание (freeze
) неинициализированной памяти, что позволило бы безопасно работать с ней, как с инициализированной.
Однако это потребовало бы изменений в языковых семантиках Rust, включая механизмы управления страницами памяти (например, MADV_FREE
).