Yandex Lança YaFF: Formato Wire Zero-Copy para Protobuf com Leitura 22× Mais Rápida

A Yandex acaba de abrir o código do YaFF (Yet another Flat Format), um formato wire zero-copy para o ecossistema Protobuf. Com licença Apache 2.0 e implementação inicial em C++ (v0.1.0), o YaFF promete leituras até 22× mais rápidas que o Protobuf tradicional e 3,8× mais rápidas que o FlatBuffers.
O problema que o YaFF resolve
Em backends de alta carga, o parsing de Protobuf pode consumir dois dígitos percentuais de CPU — o que, em escala, se traduz em milhares de núcleos físicos. A alternativa zero-copy mais comum é o FlatBuffers (também do Google), mas ele não é um substituto direto para Protobuf: exige manutenção de um schema separado e uma camada de conversão adicional.
O YaFF ataca exatamente essa lacuna: leituras zero-copy preservando a semântica do Protobuf. O arquivo .proto continua sendo a fonte única da verdade — o formato muda apenas como os dados são organizados na memória.
Como funcionam os layouts
O YaFF oferece quatro layouts que determinam como a mensagem é armazenada no buffer:
- Fixed: struct empacotada simples, sem header e schema congelado. Ideal para primitivas pequenas inline.
- Flat: adiciona um header de 2 bytes e suporta evolução de schema. Melhor para dados densos em caminhos quentes.
- Sparse: acessa campos via tabela de metadados (6 bytes de overhead), adequado para schemas esparsos com evolução livre.
- Dynamic (padrão): seleciona Flat ou Sparse em tempo de execução, usando Flat enquanto o schema permitir.
Benchmarks impressionantes
A Yandex publicou benchmarks reproduzíveis em um AMD EPYC 7713 com Clang 20.1.8. Os números mostram nanossegundos medianos por leitura:
| Formato | Tempo de leitura (ns) | Lentidão vs struct C++ |
|---|---|---|
| Struct C++ pura | 8,14 | 1,0× |
| YaFF Flat Layout | 9,79 | 1,2× |
| YaFF Sparse Layout | 21,23 | 2,6× |
| FlatBuffers | 37,30 | 4,6× |
| Protobuf | 219,35 | 26,9× |
O YaFF Flat Layout fica a apenas 1,2× da struct C++ pura — um feito notável para um formato que mantém compatibilidade com Protobuf.
Caso de uso real: economia de 10-20% de CPU
O YaFF já roda no sistema de recomendação de anúncios da Yandex, onde reporta economia de 10 a 20% de CPU em escala de produção. A adoção é incremental: basta introduzi-lo em um caminho quente, mantendo a conversão bidirecional com Protobuf nas bordas.
O código em ação
#include "feed.pb.h" // gerado pelo protoc
#include "feed.yaff.h" // gerado pelo yaff_generate()
// 1. Serializa uma mensagem Protobuf existente para buffer YaFF
feed::FeedResponse proto = LoadFeedResponse();
const auto buffer = yaff::Serialize<protoyaff::feed::FeedResponse>(proto);
// 2. Lê campos diretamente do buffer — sem parsing
const auto& response = yaff::ReadMessage<protoyaff::feed::FeedResponse>(buffer.Data());
for (const auto& item : response.items()) {
std::string_view title = item.title();
std::string_view author = item.author().name();
}
// 3. Converte de volta para Protobuf quando necessário
feed::FeedResponse restored;
response.ParseTo(restored);
Disponibilidade
O YaFF está disponível no GitHub com documentação completa em yaff.tech. A integração é feita via CMake (find_package) ou Conan. A geração de código utiliza protobuf_generate() seguido de yaff_generate(), com os tipos gerados no namespace protoyaff::<package>.
Fonte: MarkTechPost | Repositório: GitHub



