You are an expert programmer. This is my code:


fn main() {
    let start = std::time::Instant::now();

    let file = PathBuf::from(
        "/home/alejandro/Documents/projects/other_files/ensembl_gtfs/Homo_sapiens.GRCh38.110.gtf",
    );
    // let file = PathBuf::from("/home/alejandro/Documents/unam/TOGA_old_versions/x/gtf_files/1k.gtf");
    let contents = reader(&file).unwrap();
    let records = parallel_parse(&contents).unwrap();

    let mut output = File::create("/home/alejandro/Documents/test.gtf").unwrap();

    let mut layer: Vec<(String, i32, String, String)> = vec![];
    let mut mapper: HashMap<String, Vec<String>> = HashMap::new();
    let mut inner: HashMap<String, BTreeMap<Sort, String>> = HashMap::new();
    let mut helper: HashMap<String, String> = HashMap::new();

    for record in records {
        if record.chrom.is_empty() {
            // output.write_all(record.line.as_bytes()).unwrap();
            // output.write_all(b"\n").unwrap();
            continue;
        }

        match record.feature() {
            "gene" => {
                layer.push(record.outer_layer());
            }
            "transcript" => {
                let (gene, transcript, line) = record.gene_to_transcript();
                mapper
                    .entry(gene)
                    .or_insert(Vec::new())
                    .push(transcript.clone());
                helper.entry(transcript).or_insert(line);
            }
            "CDS" | "exon" | "start_codon" | "stop_codon" => {
                let (transcript, exon_number, line) = record.inner_layer();
                inner
                    .entry(transcript)
                    .or_insert(BTreeMap::new())
                    .insert(Sort::new(exon_number.as_str()), line);
            }
            _ => {
                let (transcript, feature, line) = record.misc_layer();
                inner
                    .entry(transcript)
                    .or_insert_with(|| BTreeMap::new())
                    .entry(Sort::new(feature.as_str()))
                    .and_modify(|e| {
                        e.push('\n');
                        e.push_str(&line);
                    })
                    .or_insert(line);
            }
        };
    }

    layer.par_sort_unstable_by(|a, b| {
        let cmp_chr = compare(&a.0, &b.0);
        if cmp_chr == std::cmp::Ordering::Equal {
            a.1.cmp(&b.1)
        } else {
            cmp_chr
        }
    });

    // println!("{:?}", layer);

    let mut track = true;

    for i in layer {
        if !track {
            output.write_all(b"\n").unwrap();
        } else {
            track = false;
        }

        output.write_all(i.3.as_bytes()).unwrap();
        output.write_all(b"\n").unwrap();
        let transcripts = mapper
            .get(&i.2)
            .ok_or("Error: genes with 0 transcripts are not allowed")
            .unwrap();
        for (index, j) in transcripts.iter().enumerate() {
            output.write_all(helper.get(j).unwrap().as_bytes()).unwrap();
            output.write_all(b"\n").unwrap();
            let exons = inner
                .get(j)
                .ok_or("Error: transcripts with 0 exons are not allowed")
                .unwrap();
            let joined_exons: String = exons
                .values()
                .map(|value| value.to_string())
                .collect::<Vec<String>>()
                .join("\n");
            output.write_all(joined_exons.as_bytes()).unwrap();
            if index < transcripts.len() - 1 {
                output.write_all(b"\n").unwrap();
            }
        }
    }

    println!("{} seconds", start.elapsed().as_secs_f64());
}

Do you see any room to make it faster and more efficient?