Em um exercício de otimização de chamadas de sistema, foi desenvolvida uma implementação do comando ls(1) chamada lsr, que utiliza a biblioteca de entrada e saída ourio para maximizar a eficiência das operações de IO. O resultado é uma ferramenta que se destaca pela velocidade, superando qualquer versão alternativa do ls testada e realizando um número significativamente menor de chamadas de sistema.
O funcionamento do lsr pode ser dividido em três etapas: análise de argumentos, coleta de dados e impressão dos resultados. A maior parte do IO ocorre na fase de coleta de dados, onde lsr faz uso do io_uring, uma nova interface de IO assíncrono do Linux, para acessar as informações necessárias. Isso inclui a abertura do diretório alvo e a leitura de dados de tempo, usuário e grupo, todos gerenciados através do io_uring, o que permite agrupar chamadas de sistema e reduzir a quantidade total necessária.
Os resultados das medições são impressionantes: o lsr apresenta uma redução de pelo menos uma ordem de grandeza em chamadas de sistema quando comparado ao uutils ls, seu equivalente mais próximo. Além disso, o lsr utiliza o StackFallbackAllocator da biblioteca padrão Zig, permitindo a alocação de memória de forma mais eficiente, com uma alocação inicial de 1MB, suficiente para a maioria dos usos, o que diminui ainda mais a necessidade de chamadas de mmap.
Outro ponto positivo do lsr é a sua independência da biblioteca libc, o que elimina a sobrecarga associada ao carregamento dinâmico de bibliotecas. Embora o lsr não ofereça suporte a localizações, ele é menor que o GNU ls, pesando 79,3KB comparado a 138,7KB quando compilado com a opção ReleaseSmall.
Entretanto, algumas anomalias foram observadas. Não está claro o que o lsd está fazendo, pois, segundo um strace, ele realiza chamadas a clock_gettime cerca de cinco vezes para cada arquivo, o que levanta questões sobre sua eficiência. Além disso, a ordenação dos dados parece ser um ponto crítico, com o lsr gastando aproximadamente 30% de seu tempo total nesse processo.
O projeto revelou-se uma experiência divertida e rápida de desenvolver. A utilização do io_uring para reduzir o número de chamadas de sistema foi uma surpresa positiva, e há um grande potencial para essa abordagem em aplicações mais complexas, como servidores. Para aqueles interessados, o projeto é gerido através do tangled.sh, que oferece um processo de PR interessante; sugestões e relatórios de bugs podem ser feitos diretamente no repositório com uma conta atproto e uma senha de aplicativo.
Confira os últimos vídeos publicados no canal