Executando verificação de segurança...
3

Gostei demais da iniciativa!

Porém meu instinto otimizador chamou muito a atenção nesse método: .collect();.

O Problema

Lendo a documentação do Args pode se ler o seguinte:

An iterator over the arguments of a process, yielding a String value for each argument.

E na documentação do método:

Transforms an iterator into a collection.

Um Iterador permite você percorrer do início ao final, sem poder acessar os elementos intermediários aleatóriamente. Que é exatamente a operação que você está fazendo.

A única vantagem de ter uma coleção (não todas) é justamente poder acessar qualquer elemento em qualquer ordem, o que você não está fazendo em nenhum momento.

O maior problema explicado:

O que acontece se você usar o seu comando com um arquivo de log de 1GB? Para cada palavra o método collect vai inserir em uma nova coleção, aumentando significativamente o uso de memória, sem falar na performance, para criar uma coleção pesadíssima sem toda essa necessidade.

Recomendo usar o iterator diretamente pelo método next()

Segunda evolução:

O que acontece se você usar o seu comando com um arquivo de log de 1GB?

rodando no terminal echo teste.txt todo o conteúdo desse arquivo é jogado na tela. Numa segunda versão seria interessante implementar essa funcionalidade

Carregando publicação patrocinada...
1

Muito obrigado pelo comentário! Obrigado também pelo apontamento. Sou novo no Rust e não conheço bem esses iterators, mas vou ficar ligado agora.

Não entendi bem como eu usaria o next() infinitamente, entretanto consegui remover o collect() e manter o funcionamento esperado.

Sobre a segunda evolução: pelo que pesquisei, o programa echo não lê o stdin e por isso não tem como passar arquivos para ele (a não ser que converta para string e passe como argumento). Também achei interessante, todavia deixaria para uma futura implementação do cat teste.txt, por exemplo.

1

Sou novo no Rust e não conheço bem esses iterators, mas vou ficar ligado agora.

Em Rust não sei como eles funcionam, mas já sofri muito com eles em C++, acredito que seja semelhante.

Não entendi bem como eu usaria o next() infinitamente

o next() sempre retorna o próximo elemento. um pseudocódigo ficaria assim:

fn main() {
    let mut args: Args = env::args();

    args.next(); // para remover o primeiro elemento
    
    let mut arg: String = args.next();

    let is_help_needed = arg == null || arg == "-h" || arg == "--help"
    if is_help_needed {
        println!("Example: eco-rs Bom dia!");
        exit(0);
    }

    do {
        output.push_str(&format!("{arg} "));
    while(arg = args.next())
        
    println!("{}", output.trim());
}

PS: não entendo de rust, o código pode estar incorreto, mas a intenção é essa.

PS2: não sei se no rust essa solução teria um ganho de desempenho, teria que fazer um teste de benchmarking. Estou questionando para você verificar isso.

Sobre a segunda evolução: pelo que pesquisei, o programa echo não lê o stdin e por isso não tem como passar arquivos para ele

A minha sugestão seria algo como:

if (args.len == 1 && fileExists(args[0])){
    printFile(args)
} else {
    printArgs(args)
}
4